0
votes

This is my component (let's call it BaseTable):

  <v-card>
    <v-card-title>
      {{ title }}
      <v-spacer></v-spacer>
      <v-text-field
        :value="value"
        @input="$emit('input', $event)"
        append-icon="mdi-magnify"
        label="Search"
        single-line
        hide-details
      ></v-text-field>
    </v-card-title>
    <v-data-table
      :search="value"
      :headers="headers"
      :items="items"
      :loading="loading"
      :loading-text="loadingText"
    >
      <slot></slot> <!--Will pass something here -->
    </v-data-table>
  </v-card>
</template>

Then I want to reuse BaseTable like this with a button in Actions column:

 <BaseTable
      :headers="headers"
      :items="items"
      :loading="loading"
      loadingText="Getting items... Please wait"
      title="Transfer Request Processing"
      v-model.lazy="search"
    >
      <template v-slot:item.actions="{ item }">
        <v-btn block color="warning" outlined @click="delete(item)">
          <v-icon left class="mr-2">mdi-icon</v-icon>DELETE
        </v-btn>
      </template>
    </BaseTable>

Data are displayed with proper headers but the 'DELETE' button does not. I tried using the template on the component itself (which works fine), but I don't want it that way. Thank you much for any help.

2

2 Answers

1
votes

I figured it out. I had to use scoped slots.

All I had to do was to put the following on the child component datatable:

<template v-for="(slot, name) in $scopedSlots" v-slot:[name]="item">
   <slot :name="name" v-bind="item"></slot>
</template>

Then in the parent:

<template v-slot:item.actions="{ item }">
   <v-btn block color="warning" outlined @click="delete(item)">
      <v-icon left class="mr-2">mdi-icon</v-icon>DELETE
   </v-btn>
</template>

After reading the two articles below, I got to work but I still do not fully understand the science behind it given that I am new to Vue.js

https://vuejsdevelopers.com/2017/10/02/vue-js-scoped-slots/

and

https://css-tricks.com/using-scoped-slots-in-vue-js-to-abstract-functionality/

(The two articles that helped me).

0
votes

Yes, it's possible to pass slot content to a grandchild.

It involves using a named slot element in the descendant (your BaseTable) and a template element with v-slot in the higher component. Something like:

// BaseTable
...
    <slot name="actions :props></slot>
...

// Parent
<BaseTable>
    <template v-slot:actions="props"></template>
</BaseTable>