vue.jsvue-componentvuejs3vuejs-slots

Creating a custom component Vue3js


I downloaded the DataTable component vue3-easy-data-table. Then I created a custom component where I define the theme for the table. Since the easy-data-table uses slots to operate on the table items, how can I redirect my template tags to the table instead of my custom component?

<script>

export default {
    setup() {
        const themeColor = getComputedStyle(document.documentElement).getPropertyValue('--primary');

        return { themeColor }
    }
}
</script>

<template>
    <DataTable table-class-name="table-theme" :theme-color="themeColor" alternating>

        <template #expand="item">
            <slot name="expand" v-bind="item"></slot>
        </template>
    </DataTable>
</template>

<style lang="scss" scoped>
.table-theme {
    width: 100%;
    height: 100%;

    overflow: hidden;
}
</style>

This is my custom component. At the moment I manually created a copy template for the expand function and it works alright, but not only it looks ugly and redundant, it also won't work to access specific items. Do you have a solution?


Solution

  • I found a solution. The slots object that you get in your setup function will contain the "parent requested slot" even if they are not defined in the template.

    Therefore you can easily pass the slots names to the template, iterate through them and automatically generate the needed slots.

    <script>
    
    export default {
        setup(props, { slots }) {
            const themeColor = getComputedStyle(document.documentElement).getPropertyValue('--primary');
    
            const slotNames = Object.keys(slots)
    
            return { themeColor, slotNames }
        }
    }
    </script>
    
    <template>
        <DataTable table-class-name="table-theme" :theme-color="themeColor" alternating>
            <template v-slot:[slot]="model" v-for="slot in slotNames">
                <slot :name="slot" v-bind="model"></slot>
            </template>
        </DataTable>
    </template>