Dynamic Slot Names Usage

I just wan’t to be sure if this is the right way to name and use slots dynamicaly. I’m not having any problem with this, the problem is that despite it works, I can’t find anyone or any docs doing this so I decided publish a post here so you guys can j…


This content originally appeared on DEV Community and was authored by dtechmaster

I just wan't to be sure if this is the right way to name and use slots dynamicaly. I'm not having any problem with this, the problem is that despite it works, I can't find anyone or any docs doing this so I decided publish a post here so you guys can judge this code and point eventual problems that I'm not seeing.

My environment

Nuxt 3

d-virtual-table Component

description: The component purpose is a table with slots that I can use named dynamically based on my input values so I can replace default components by a column.field or a column.type based on the need when creating a page/screen.

<template>
    <RecycleScroller class="scroller" :items="rows" :item-size="63" key-field="name" listTag="table"
        listClass="data-table" itemTag="tr" itemClass="" :buffer="200">
        <template #before="{ item: row }">
            <table class="data-table">
                <thead>
                    <tr class="data-table-header">
                        <th v-for="column in columns">
                            <slot :name="`column-${column.field}`" :row="row" :column="column" :value="column.field"
                                >
                                <slot :name="`column-${column.type}`" :row="row" :column="column" :value="column.field"
                                    >
                                    {{ column.field }} ({{ column.type }})
                                </slot>
                            </slot>
                        </th>


                    </tr>
                </thead>
            </table>
        </template>

        <template #default="{ item: row, index }">
            <td v-for="col in columns" :class="getOddEven(index)">
                <slot :name="col.field" :row="row" :column="col" :value="row[col.field]" :index="index">
                    <slot :name="col.type" :row="row" :column="col" :value="row[col.field]" :index="index">
                        {{ row[col.field] }} 
                    </slot>
                </slot>
            </td>


        </template>
    </RecycleScroller>
</template>


<script setup lang="ts">
interface Column {
    label: string
    field: string
    type?: string
    dateOutputFormat?: string
    dateInputFormat?: string
}
interface Row {
    id: number
    name: string
    age: number
    createdAt: string
    score: number
}
defineProps<{
    columns: Column[]
    rows: Row[]
}>()

function getOddEven(index: number) {
    if (typeof index !== 'number') {
        return '';
    }
    return index % 2 === 0 ? 'row-even' : 'row-odd';
}
</script>

<style>
.scroller {
    height: 100%;
}

.user {
    height: 32%;
    padding: 0 12px;
    display: flex;
    align-items: center;
}

.data-table {
    border-collapse: collapse !important;
    width: 100%;
}

.data-table tr {
    width: 100%;
    display: flex;
}

.data-table td,
.data-table th {
    padding: 10px 15px;
    border: 1px solid black;
    flex: 1;
}

.data-table-header th {
    font-weight: 700;
    padding: 10px 15px;
    border: 1px solid black;
}

.row-odd {
    background-color: white;
}

.row-even {
    background-color: rgba(210, 210, 210, 0.507);
}

tbody {
    display: block;
}
</style>

Component usage

<template>
    <div class="page-wrapper">
    <!-- <d-virtual-table :rows="rows" :columns="columns" /> -->
     <d-virtual-table :rows="rows" :columns="columns">
        <template #column-name="{row, column, value}">
            {{ value }} (ABC)
        </template>

        <template #column-age="{row, column, value}">
            {{ value }} (N)
        </template>

        <template #column-date="{row, column, value}">
            {{  value }} yy/mm/dd
        </template>

        <template #column-score="{row, column, value}">
            {{ value }} (%)
        </template>

        <template #string="{row,column,value}">
            <v-text-field density="compact" variant="outlined" hide-details type="text" :label="column.label" v-model="row[column.field]" />
        </template>

        <template #score="{row,column,value}">
            <v-chip class="border" type="text" v-model="row[column.field]" :text="value"/> %
        </template>
     </d-virtual-table>
    </div>
</template>

<script setup lang="ts">
const columns = [
    {
        label: 'Name',
        field: 'name',
        type: 'string'
    },
    {
        label: 'Age',
        field: 'age',
        type: 'number',
    },
    {
        label: 'Created On',
        field: 'createdAt',
        type: 'date',
        dateInputFormat: 'yyyy-MM-dd',
        dateOutputFormat: 'MMM do yy',
    },
    {
        label: 'Percent',
        field: 'score',
        type: 'string',
    },
];

const rows = [
    { id: 1, name: "John", age: 20, createdAt: '', score: 0.03343 },
    { id: 2, name: "Jane", age: 24, createdAt: '2011-10-31', score: 0.03343 },
    { id: 3, name: "Susan", age: 16, createdAt: '2011-10-30', score: 0.03343 },
    { id: 4, name: "Chris", age: 55, createdAt: '2011-10-11', score: 0.03343 },
    { id: 5, name: "Dan", age: 40, createdAt: '2011-10-21', score: 0.03343 },
    { id: 6, name: "John", age: 20, createdAt: '2011-10-31', score: 0.03343 },
];
</script>

<style scoped>
.page-wrapper {
    height: 100dvh;
    max-height: 100dvh;
    overflow: hidden;
}
</style>

The only thing I found about this is the bellow vue 3 docs which seems wrong or incomplete? looks like just the usage part is here or am I just not getting this?

https://vuejs.org/guide/components/slots.html#dynamic-slot-names
https://vuejs.org/guide/components/slots.html#dynamic-slot-names

Well, that's it. anything wrong with this? Thank very much for you guys time.


This content originally appeared on DEV Community and was authored by dtechmaster


Print Share Comment Cite Upload Translate Updates
APA

dtechmaster | Sciencx (2024-09-24T06:44:12+00:00) Dynamic Slot Names Usage. Retrieved from https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/

MLA
" » Dynamic Slot Names Usage." dtechmaster | Sciencx - Tuesday September 24, 2024, https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/
HARVARD
dtechmaster | Sciencx Tuesday September 24, 2024 » Dynamic Slot Names Usage., viewed ,<https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/>
VANCOUVER
dtechmaster | Sciencx - » Dynamic Slot Names Usage. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/
CHICAGO
" » Dynamic Slot Names Usage." dtechmaster | Sciencx - Accessed . https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/
IEEE
" » Dynamic Slot Names Usage." dtechmaster | Sciencx [Online]. Available: https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/. [Accessed: ]
rf:citation
» Dynamic Slot Names Usage | dtechmaster | Sciencx | https://www.scien.cx/2024/09/24/dynamic-slot-names-usage/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.