Vue 3에서 동적 슬롯 이름으로 테이블 구성 요소 빌드
20792 단어 vuejavascriptwebdevtutorial
slot
을 사용할 수 있는 기능입니다.무엇보다도 이것은 자식 배열 내에서 원하는 위치에 정확하게 데이터를 주입하는 정말 강력한 방법을 제공합니다.
그것은 우리에게 무엇을 의미합니까? 자, 알아보기 위해 SimpleTable 구성 요소를 빌드해 보겠습니다.
items
이라는 개체 배열을 기반으로 행을 자동으로 빌드하는 테이블 구성 요소를 제공한다고 가정해 보겠습니다.const items = ref([
{ id: 1, title: 'First entry', description: 'Lorem ipsum' },
{ id: 1, title: 'Second entry', description: 'Sit dolar' },
])
열을 빌드하기 위해
fields
이라는 다른 개체 배열을 사용하겠습니다.const fields = ref([
{ key: 'title', label: 'Title' },
{ key: 'description', label: 'Description' }
])
items
및 fields
이 정의된 상태에서 테이블을 다음과 같이 사용하고 싶습니다.<SimpleTable :items="items" :fields="fields" />
항목과 필드를 반복하는 몇 개의
v-for
문과 약간의 논리만 있으면 행과 열을 자동으로 생성하는 SimpleTable 구성 요소를 구축할 수 있습니다.<template>
<table>
<thead>
<tr>
<th v-for="field in fields" :key="field.key">
{{ field.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td v-for="key in displayedFieldKeys">
{{ item[key] }}
</td>
</tr>
</tbody>
</table>
</template>
<script lang="ts" setup>
import { computed, PropType } from 'vue';
interface TableField {
key: string
label: string
}
interface TableItem {
id: number
[key: string]: unknown
}
const props = defineProps({
fields: {
type: Array as PropType<TableField[]>,
default: () => []
},
items: {
type: Array as PropType<TableItem[]>,
default: () => []
}
})
const displayedFieldKeys = computed(() => {
return Object.entries(props.fields).map(([_key, value]) => value.key)
})
</script>
완전 멋지죠!? 그러나 필드 키를 기반으로 멋진 테이블 셀의 내용을 수정하려면 어떻게 해야 할까요? 예를 들어 제목을 굵게 표시하거나 각 셀에 추가 데이터를 삽입합니다.
구조에 대한 동적 슬롯 이름!
다음 슬롯 중 하나에 각 테이블 셀의 내용을 래핑해 보겠습니다.
...
<tr v-for="item in items" :key="item.id">
<td v-for="key in displayedFieldKeys">
<slot
:name="`cell(${key})`"
:value="item[key]"
:item="item"
>
{{ item[key] }}
</slot>
</td>
</tr>
...
이제 필드 키를 기반으로 셀 집합의 내용을 수정하려고 할 때마다 다음과 같이 할 수 있습니다.
<SimpleTable :items="items" :fields="fields">
<template #cell(title)="{ value, item }">
<p>A bold item title: <strong>{{ value }}</strong></p>
<p>Item ID for some reason: {{ item.id }}</p>
</template>
</SimpleTable>
니토! 이제 과도한 마크업을 처리할 필요 없이 수정하려는 콘텐츠를 정확히 찾아낼 수 있습니다.
도대체 나는
caption
지원, col
스타일 지정, 필드 숨기기 및 형식 지정, 셀에 th
또는 td
사용 여부 결정과 같은 몇 가지 추가 기능이 있는 이 테이블 구성 요소의 약간 더 강력한 버전을 구축했습니다.열 정렬은 이 문서의 향후 개정판에서 제공될 예정입니다.
<template>
<table>
<caption v-if="!!$slots.caption || caption">
<slot name="caption">{{ caption }}</slot>
</caption>
<colgroup>
<template v-for="field in displayedFields" :key="field.key">
<slot :name="`col(${field.key})`">
<col>
</slot>
</template>
</colgroup>
<thead>
<tr>
<th v-for="field in displayedFields">
<slot :name="`head(${field.key})`" :field="field">
{{ field.label }}
</slot>
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<template v-for="key in displayedFieldKeys">
<Component :is="cellElement(key as string)">
<slot
:name="`cell(${key})`"
:value="format(item, (key as string))"
:item="item"
:format="(k: string) => format(item, k)"
>
{{ format(item, (key as string)) }}
</slot>
</Component>
</template>
</tr>
</tbody>
</table>
</template>
<script lang="ts" setup>
import { computed, PropType } from 'vue';
interface TableField {
key: string
label: string
format?: Function
hidden?: boolean
header?: boolean
}
interface TableItem {
id: number
[key: string]: unknown
}
const props = defineProps({
fields: { type: Array as PropType<TableField[]>, default: () => [] },
items: { type: Array as PropType<TableItem[]>, default: () => [] },
caption: { type: String, default: null }
})
const displayedFields = computed(() => props.fields.filter((i) => !i.hidden))
const displayedFieldKeys = computed(() => {
return Object.entries(displayedFields.value).map(([_key, value]) => value.key)
})
const cellElement = (key: string) => {
const field = props.fields.find((f) => f.key === key)
return field && field.header ? 'th' : 'td'
}
const format = (item: TableItem, key: string) => {
const field = props.fields.find((f) => f.key === key)
return field && field.format ? field.format(item[key]) : item[key]
}
</script>
도움이 되었기를 바랍니다.
감사!
Reference
이 문제에 관하여(Vue 3에서 동적 슬롯 이름으로 테이블 구성 요소 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ajscommunications/the-awesome-dynamic-slot-name-in-vue-3-574k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)