Search code examples
vue.jsdatatablecomponentsvuetify.jsparent-child

How to use vuetify 3 data-table v-slot functionalities inside a custom component?


I want to get v-data-table items and headers using slots from my custom component.

Custom Component: @/components/MyDataTable.vue

<template>
  <div>
    <v-data-table :headers="headers" :items="items"> </v-data-table>
  </div>
</template>

<script>
export default {
  props: {
    items: {
      type: Array,
      default: () => [],
    },
    headers: {
      type: Array,
      default: () => [],
    },
  },
};
</script>

App.vue

<template>
  <v-app>
    <v-main>
      <my-data-table :headers="headers" :items="items" item-value="name">
        <template v-slot:[`column.name`]="{ column }">
          {{ column }}
        </template>
        <template v-slot:[`item.name`]="{ item }">
          {{ item.props }}
        </template>
      </my-data-table>
    </v-main>
  </v-app>
</template>

<script>
import MyDataTable from "@/components/MyDataTable.vue";

export default {
  components: {
    MyDataTable,
  },
  data() {
    return {
      headers: [
        { title: "Dessert", align: "start", key: "name" },
        { title: "Calories", align: "end", key: "calories" },
        { title: "Fat (g)", align: "end", key: "fat" },
      ],
      items: [
        {
          name: "Frozen Yogurt",
          calories: 159,
          fat: 6.0,
        },
        {
          name: "Jelly bean",
          calories: 375,
          fat: 0.0,
        },
      ],
    };
  },
};
</script>

If I put them in the native component they work, but if I put them in my own they do not work.

Expected Result: enter image description here

Active Result: enter image description here

I use vue 3 with vuetify 3.

Here is the codesandbox ready link.


Solution

  • Try to forward the slots from the v-datatable by iterating over them, then creating new ones that can be accessed in parent component :

    <v-data-table :headers="headers" :items="items"> 
       <template v-for="(_, scopedSlotName) in $scopedSlots" v-slot:[scopedSlotName]="slotData">
            <slot :name="scopedSlotName" v-bind="slotData" />
       </template>
    </v-data-table>