Home > front end >  Vuejs 3 how to pass variable to all elements inside a slot
Vuejs 3 how to pass variable to all elements inside a slot

Time:07-13

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:

  1. In MyTable.vue, bind the value of index and row to the <slot>:
<tr v-for="(row, index) in $props.source" :key="index">
  <slot :index="index" :row="row"></slot>
</tr>
  1. In App.vue, access MyTable.vue's slot props via v-slot on a <template>, and bind them to the MyTableColumn's props:
<MyTable
  :source="[
    { fname: 'Jhon', lname: 'Smith' },
    { fname: 'Arthur', lname: 'Cromer' },
  ]"
>
                                      
  • Related