如何为基于v-data-table封装的通用组件传递带item参数的自定义子模板
调整方案
你遇到的两个问题核心原因有两个:
- 封装的组件未暴露
item.state这类名称的插槽,所以直接写同名插槽不生效 - 手动映射的
state插槽没有把v-data-table传递的作用域参数透传给父级,导致拿不到item
要实现任意自定义插槽透传,推荐用动态插槽方案,不需要手动为每个字段写插槽映射:
第一步:修改DataTableFuntional组件代码
<template> <div> <v-data-table class="tableBackground" :dense="dense" :headers="headers" :items="items.data" :options.sync="options" no-data-text="No hay datos disponibles" :loading-text="$t('comunes.general.cargando')" > <!-- 动态透传所有父级传入的作用域插槽 --> <template v-for="(slot, name) in $scopedSlots" v-slot:[name]="slotProps" :key="name" > <slot :name="name" v-bind="slotProps" /> </template> <!-- 预设全局通用模板,优先级比动态插槽高,不会被覆盖 --> <template v-slot:item.index="{ item }"> {{ items.data.indexOf(item) + 1 }} </template> <template v-slot:body.append> <slot name="body2"></slot> </template> <!-- 如果要给某个插槽加默认 fallback 内容,可以单独写,示例:state字段默认模板 --> <!-- <template v-slot:item.state="{ item }"> <div v-if="!$scopedSlots['item.state']"> <span v-if="item.state === 1" color="red">Close</span> <span v-else-if="item.state === 2" color="green">Open</span> </div> <slot v-else name="item.state" :item="item" /> </template> --> </v-data-table> </div> </template>
第二步:使用组件时直接写对应插槽即可,和v-data-table原生用法完全一致
<DataTableFuntional ref="reference" :endpoint="item.endpoint" :headers="item.headers" :actions="item.actions" :btsmall="true" > <!-- 自定义state列模板 --> <template v-slot:item.state="{ item }"> <div> <span v-if="item.state === 1" color="red">Close</span> <span v-else-if="item.state === 2" color="green">Open</span> </div> </template> <template v-slot:body2> <tr> <td></td> <td> <v-text-field type="number" label="Less than" ></v-text-field> </td> <td colspan="4"></td> </tr> </template> </DataTableFuntional>
可选的轻量调整方案
如果不需要全量透传插槽,只想保留你原来的手动映射写法,只需要给插槽透传参数即可:
<!-- DataTableFuntional组件内的插槽映射 --> <template v-slot:item.state="{ item }"> <slot name="state" :item="item"></slot> </template>
使用时对应写法:
<template v-slot:state="{ item }"> <!-- 这里就可以正常拿到item参数 --> </template>
内容的提问来源于stack exchange,提问作者diegoAuto
相关产品推荐
相关产品推荐

