Vue3+Vuetify3中v-table访问desserts变量报错无法渲染求助
问题与解决:Vuetify v-table 无法访问组件数据的警告
问题
触发警告:Property was accessed during render but is not defined on instance
使用Vuetify 3的<v-table>组件时,尝试在内部通过v-for遍历根组件的desserts数据,会触发上述警告,表格无法正常渲染;但将<v-table>替换为原生<table>后,表格能正常显示数据。
原因
Vuetify的<v-table>是封装的Vue组件,会创建独立的组件实例,内部模板的作用域和根组件作用域隔离。直接在<v-table>内部的<tbody>中访问根组件的desserts变量,会因为当前组件实例(v-table的实例)没有该属性而报错。而原生<table>不是Vue组件,不会创建新实例,因此可以直接访问根组件的数据。
解决方案
使用Vuetify <v-table>的官方规范用法,通过组件属性传递数据并利用插槽渲染内容,有两种常见写法:
写法一:自定义表头和行插槽
<div id="app"> <v-table :items="desserts"> <!-- 自定义表头插槽 --> <template v-slot:header> <thead> <tr> <th class="text-left">Name</th> <th class="text-left">Calories</th> </tr> </thead> </template> <!-- 自定义行插槽,通过item参数获取当前行数据 --> <template v-slot:item="{ item }"> <tr> <td>{{ item.name }}</td> <td>{{ item.calories }}</td> </tr> </template> </v-table> </div>
写法二:使用v-table-column组件
这种写法更贴合Vuetify组件设计,无需手动编写thead和tr:
<div id="app"> <v-table :items="desserts"> <v-table-column title="Name" class="text-left"> <template v-slot:default="{ item }"> {{ item.name }} </template> </v-table-column> <v-table-column title="Calories" class="text-left"> <template v-slot:default="{ item }"> {{ item.calories }} </template> </v-table-column> </v-table> </div>
备选方案:保留原生table结构
如果想要保留原生表格写法,同时使用Vuetify样式,可以用Vuetify卡片容器包裹原生table:
<div id="app"> <v-card> <v-card-text> <table> <thead> <tr> <th class="text-left">Name</th> <th class="text-left">Calories</th> </tr> </thead> <tbody> <tr v-for="item in desserts" :key="item.name"> <td>{{ item.name }}</td> <td>{{ item.calories }}</td> </tr> </tbody> </table> </v-card-text> </v-card> </div>
代码说明
JavaScript部分无需修改,原有的数据定义和框架初始化逻辑均正确:
const { createApp } = Vue; const { createVuetify } = Vuetify; const vuetify = createVuetify(); const app = createApp({ data() { return { desserts: [ { name: 'Frozen Yogurt', calories: 159 }, { name: 'Ice cream sandwich', calories: 237 }, { name: 'Eclair', calories: 262 }, { name: 'Cupcake', calories: 305 }, { name: 'Gingerbread', calories: 356 }, { name: 'Jelly bean', calories: 375 }, { name: 'Lollipop', calories: 392 }, { name: 'Honeycomb', calories: 408 }, { name: 'Donut', calories: 452 }, { name: 'KitKat', calories: 518 }, ], } }, }); app.use(vuetify).mount('#app'); app.config.errorHandler = (err, instance, info) => { console.error(err); console.log(instance); console.info(info); }
内容的提问来源于stack exchange,提问作者nemiloc
相关产品推荐
相关产品推荐

