On gists
Function in props
•
Vue.js
example.vue
Raw
#
// DataGrid.vue
<script setup>
const props = defineProps({
items: {
type: Array,
required: true
},
// Render funkce pro transformaci dat nebo komplexní logiku
cellRenderer: {
type: Function,
default: null
},
// Funkce pro custom formátování dat v buňce
formatters: {
type: Object,
default: () => ({})
}
})
const formatCell = (value, column) => {
// Pokud existuje custom formatter pro tento sloupec, použij ho
if (props.formatters[column]) {
return props.formatters[column](value)
}
// Základní formátování podle typu dat
if (value instanceof Date) {
return value.toLocaleDateString()
}
if (typeof value === 'number') {
return value.toLocaleString()
}
return value
}
</script>
<template>
<div class="data-grid">
<slot name="header" />
<div class="grid-body">
<template v-for="item in items" :key="item.id">
<!-- Prioritně použij slot pokud existuje -->
<slot
name="row"
:item="item"
:format="formatCell"
>
<!-- Fallback na render funkci -->
<template v-if="cellRenderer">
{{ cellRenderer(item, formatCell) }}
</template>
<!-- Základní fallback -->
<template v-else>
<div class="grid-row">
<div
v-for="(value, key) in item"
:key="key"
class="grid-cell"
>
{{ formatCell(value, key) }}
</div>
</div>
</template>
</slot>
</template>
</div>
<slot name="footer" />
</div>
</template>
// Použití:
<script setup>
const data = [
{
id: 1,
name: 'Produkt 1',
price: 1299.99,
lastUpdated: new Date('2024-03-15'),
status: 'active'
},
// ...
]
// Custom formátování pro specifické sloupce
const formatters = {
price: (value) => `${value.toLocaleString()} Kč`,
status: (value) => ({
'active': '✅ Aktivní',
'inactive': '❌ Neaktivní'
}[value] || value)
}
// Komplexní transformace dat
const renderComplexRow = (item, format) => {
const statusClass = item.status === 'active' ? 'text-green' : 'text-red'
return `
<div class="grid-row">
<div class="font-bold">${item.name}</div>
<div>${format(item.price, 'price')}</div>
<div class="${statusClass}">${format(item.status, 'status')}</div>
<div>${format(item.lastUpdated)}</div>
</div>
`
}
</script>
<template>
<!-- Základní použití se slotem -->
<DataGrid :items="data" :formatters="formatters">
<template #row="{ item, format }">
<div class="grid-row">
<div>{{ item.name }}</div>
<div>{{ format(item.price, 'price') }}</div>
<div>{{ format(item.status, 'status') }}</div>
</div>
</template>
</DataGrid>
<!-- Použití s render funkcí pro specifické případy -->
<DataGrid
:items="data"
:formatters="formatters"
:cell-renderer="renderComplexRow"
/>
</template>
example2.vue
Raw
#
// BaseList.vue
<script setup>
const props = defineProps({
items: {
type: Array,
required: true
},
renderItem: {
type: Function,
required: true
},
filterFn: {
type: Function,
default: (item) => true
},
sortFn: {
type: Function,
default: (a, b) => 0
}
})
const processedItems = computed(() => {
return props.items
.filter(props.filterFn)
.sort(props.sortFn)
})
</script>
<template>
<div class="base-list">
<div v-for="item in processedItems" :key="item.id">
<!-- Zde voláme předanou render funkci místo pevného templatu -->
{{ renderItem(item) }}
</div>
</div>
</template>
// Použití v parentovi:
<template>
<BaseList
:items="users"
:render-item="(user) => `${user.name} (${user.role})`"
:filter-fn="(user) => user.active"
:sort-fn="(a, b) => a.name.localeCompare(b.name)"
/>