Home > Net >  Creating a custom component Vue3js
Creating a custom component Vue3js

Time:02-02

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?

CodePudding user response:

You don't really need to wrap the table with a custom component.

But unfortunately the vue3-easy-data-table does not update with changing the themeColor.

So, the quick and dirty solution is to force the table recreate, by destroying it using v-if.

Here is the playground (check it in the full page)

const App = {
    components: {
      EasyDataTable: window['vue3-easy-data-table'],
    },
    data () {
      return {
        themeColor: "#f48225",
        headers:[
          { text: "Name", value: "name" },
          { text: "Age", value: "age", sortable: true }
        ],
        items: [
          { "name": "Curry", "height": 178, "weight": 77, "age": 20 },
          { "name": "James", "height": 180, "weight": 75, "age": 21 },
          { "name": "Jordan", "height": 181, "weight": 73, "age": 22 }
        ],
      }
    },
    methods: {
      resetTable() {
        this.themeColor = null;
      }
    }
  };
  Vue.createApp(App).mount('#app');
<div id="app">
  Theme Color: {{themeColor}}<br /><br />
 <input type="radio" v-model="themeColor" value="#f48225" @input="resetTable"/> #f48225 
 <input type="radio" v-model="themeColor" value="#123456" @input="resetTable" /> #123456 <br /><br />
  <easy-data-table v-if="themeColor != null"
    :headers="headers"
    :items="items"
    :theme-color="themeColor"
    buttons-pagination
    alternating
  />
</div>
<link href="https://unpkg.com/vue3-easy-data-table/dist/style.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue3-easy-data-table"></script>

CodePudding user response:

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>
  • Related