Reputation: 105
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.
Upvotes: 2
Views: 2483
Reputation: 105
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).
Upvotes: 6
Reputation: 7553
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>
Upvotes: 1