Vuetify v-data-table的item-expanded事件服务端加载数据展开显示异常
问题根因
这个问题是Vue响应式侦测规则限制导致的:你传入v-data-table的records数组中的每一项初始化时没有预先声明details属性,异步请求完成后直接通过item.details = 数据的方式赋值,Vue无法识别这个新增的响应式属性,不会触发展开插槽的重新渲染。第一次触发展开时插槽已经渲染完成,此时details还未赋值,所以只会展示表头;折叠后再次展开时details已经挂载到item对象上,就能正常读取数据渲染。
修复方案
方案1(推荐,兼容Vue2/Vuetify2环境)
使用Vue提供的$set方法给item添加响应式属性,修改loadDetails方法的赋值逻辑即可:
loadDetails: function({item}) { if (item.details) return; this.ChildApiCall(item).then((data) => { // 替换原有的直接赋值逻辑 this.$set(item, 'details', data.response) }) },
方案2(预处理数据)
你也可以在拿到列表接口的records数据时,预先给每一项初始化details字段:
// 列表请求回调中预处理数据 this.records = 接口返回的列表数据.map(item => { return { ...item, details: null // 预先声明响应式属性 } })
方案3(体验优化)
可以给展开插槽加加载状态,避免用户看到空表头:
<template v-slot:expanded-item="{ headers, item }"> <td :colspan="headers.length"> <div v-if="item.details === undefined">加载中...</div> <table v-else> <!-- 原有表格代码保持不变 --> <thead> <tr> <th data-field="id" data-visible="false">id</th> <th data-field="league_id" >league_id</th> <th data-field="Start" >Start</th> <th data-field="End" >End</th> <th data-field="Current" >Current</th> </tr> </thead> <tbody> <tr v-for="rec in item.details" :key="rec.id"> <td>{{ rec.id }}</td> <td>{{ rec.league_id }}</td> <td>{{ rec.start }}</td> <td>{{ rec.end }}</td> <td>{{ rec.current }}</td> </tr> </tbody> </table> </td> </template>
问题复现效果

内容的提问来源于stack exchange,提问作者Zakari
相关产品推荐
相关产品推荐

