I'm using VueJs 3 to create a dynamic table component, which involves sending down loop index variable to all child components inside a slot
the usage of the component as following
<template>
<h1>my table</h1>
<MyTable
:source="[
{ fname: 'Jhon', lname: 'Smith' },
{ fname: 'Arthur', lname: 'Cromer' },
]"
>
<MyTableColumn cellTitle="First Name" cellValue="fname"></MyTableColumn>
<MyTableColumn cellTitle="Last Name" cellValue="lname"></MyTableColumn>
</MyTable>
</template>
The above shows what i am trying to achieve in which you may set the table data source (array) and any number of columns where each column accepts a title and cell value.
I'm not sure how to send the iteration index (v-for index) down to all components within a slot.
here is the MyTable.vue template
<template>
<table>
<tr v-for="(row, index) in $props.source" :key="index">
{{
(currentRow = index)
}}
<slot></slot>
</tr>
</table>
</template>
I've tried scoped slots but did not help. and tried the provide/inject technique by providing the index from MyTable.vue and injecting it in each instance of MyTableColumn.vue, but this hasn't worked as expected because the injected variable always has the last index. not sure if it requires usage of render function.
I've have spent the last couple of days trying to find a solution with no luck.
here you can access the full code demo which has the unexpected behaviour
CodePudding user response:
Rendering rows
You can use scoped slots to pass data from MyTable.vue
to its slot children:
- In
MyTable.vue
, bind the value ofindex
androw
to the<slot>
:
<tr v-for="(row, index) in $props.source" :key="index">
<slot :index="index" :row="row"></slot>
</tr>
- In
App.vue
, accessMyTable.vue
's slot props viav-slot
on a<template>
, and bind them to theMyTableColumn
's props:
<MyTable
:source="[
{ fname: 'Jhon', lname: 'Smith' },
{ fname: 'Arthur', lname: 'Cromer' },
]"
>