如何在Vuetify的expanded-item插槽中用v-show替代默认v-if?
解决方案
Vuetify 的 v-data-table 默认通过 v-if 控制展开行的渲染,未展开时组件会被销毁,导致无法访问实例。要实现始终能访问 CustomComponent,可以绕过默认的 expanded-item 插槽,自行实现展开行的显示逻辑,用 v-show 替代 v-if:
- 维护一个记录各行展开状态的对象,替代 Vuetify 内置的展开状态
- 在表格的
item插槽中,额外添加一行作为展开内容,用v-show控制显示/隐藏 - 调整展开按钮的点击逻辑,切换对应行的展开状态
完整代码示例
<template> <v-data-table :items="yourItemsData"> <!-- 自定义表格行及展开按钮 --> <template v-slot:item="{ item }"> <tr> <td> <v-btn @click="toggleExpand(item.id)"> {{ expandedRows[item.id] ? '折叠' : '展开' }} </v-btn> </td> <td class="d-block d-sm-table-cell" v-for="field in Object.keys(item)" :key="field"> {{ item[field] }} </td> </tr> <!-- 自定义展开行,用v-show控制显示 --> <tr v-show="expandedRows[item.id]"> <!-- colspan值为表格总列数(数据列数+展开按钮列) --> <td :colspan="Object.keys(item).length + 1"> <CustomComponent :ref="`custom-comp-${item.id}`" /> </td> </tr> </template> </v-data-table> </template> <script> import CustomComponent from './CustomComponent.vue' export default { components: { CustomComponent }, data() { return { expandedRows: {}, // 记录每行的展开状态 yourItemsData: [] // 你的表格数据源 } }, methods: { toggleExpand(itemId) { this.$set(this.expandedRows, itemId, !this.expandedRows[itemId]) }, // 随时访问指定item的CustomComponent实例 getComponentInstance(itemId) { // $refs返回的是数组,取第一个元素 return this.$refs[`custom-comp-${itemId}`]?.[0] } } } </script>
关键说明
- 用
v-show控制展开行的显示,组件会始终渲染在DOM中,只是通过CSS隐藏,因此可以随时通过ref访问实例 - 手动维护
expandedRows对象记录展开状态,避免依赖 Vuetify 内置的展开逻辑 - 展开行的
colspan必须设置为表格总列数,否则会导致表格布局错乱 ref命名加入item.id保证唯一性,避免多个组件实例冲突
内容的提问来源于stack exchange,提问作者faezeh
相关产品推荐
相关产品推荐

