- 最近写需求时用到了
expand-change
表格展开回调,但我发现第一次展开后并没有展示任何数据,但我的返回值是存在的,当第二次展开时发现数据就有了。此原因是因为获取数据的接口是异步的,导致Dom渲染不同步导致的,其实解决办法也很简单,只需在外层的表格列表中的每一个数组对象加一个空数组用来存储嵌套的数据列表,这样的话每次渲染,都能获取到这个存在的列表
- 由于内嵌表格数据过于庞大,需做表格懒加载,所以需要获取到页面元素位置等,还需要持续触发,此时就用到了命令,当满足特定条件就触发页数+1,并触发获取内嵌列表的数据
1 . 解决expand-change第一次展开无数据显示问题
- 首先:定义好需要展示的数据并设置
type="expand"
展开子表格,用expand-change
来获取当前行展开回调,设置row-key
防止数据混乱
<el-table :data="dataList" border row-key="id" @expand-change="dataListSelectionChangeHandle" style="width: 100%;" >
<el-table-column type="expand" >
<template slot-scope="scope">
<el-table v-loading="dataListLoading" :row-key="scope.row.child.id" :data="scope.row.child" border style="width: 100%;" >
<el-table-column prop="categoryRef" label="类目ref" header-align="center" align="center" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="addInfo" label="附加信息" header-align="center" align="center" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="benefitsMealRef" label="权益套餐ID" header-align="center" align="center" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="cardNo" label="会员卡号" header-align="center" align="center" :show-overflow-tooltip="true"></el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column prop="merchantName" label="商户" header-align="center" align="center"></el-table-column>
<el-table-column prop="mealName" label="套餐名称" header-align="center" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建日期" header-align="center" align="center"></el-table-column>
<el-table-column prop="updateTime" label="更新日期" header-align="center" align="center"></el-table-column>
</el-table>
- 获取回调时向外层表格列表添加一个空数组,并处理Dom渲染不同步问题
data() {
return {
BenefitsMealDetailPageReq: { // 请求列表参数
pageNum : 1,
pageSize : 10
},
timeout: null // 防抖用
dataList: [], // 外层表格列表数据
dataRow: [] // 当前行的数据列表(由于子表格是内嵌的,所以也有子表格的所有数据)
},
methods:{
// 展开列回调函数
dataListSelectionChangeHandle(row,key){
// 存储当前行的数据
this.dataRow=row
// 由于expand-change对于异步加载第一轮dom不渲染先加一个存在的dom让接口返回值可以渲染
this.dataList.forEach(item => {
item.child=[]
})
// 只有展开列才会触发接口
if(key.length!==0){
// 确保第一次展开请求第一页数据
this.BenefitsMealDetailPageReq.pageNum=1
this.getTableList(row)
}
},
// 请求权益明细表格
async getTableList(){
const res=await this.$http.post('',this.BenefitsMealDetailPageReq)
if (res.status==200) {
this.totalCount=res.data.data.pagination
this.dataRow.child.push(...res.data.data.resultData)
}
},
}
2 . 处理表格懒加载问题
- 以下只写关键代码,样式与代码位置请参考上面(会写注释标记位置)
<template>
<el-table :data="dataList" border row-key="id" @expand-change="dataListSelectionChangeHandle" style="width: 100%;" >
<el-table-column type="expand" >
<template slot-scope="scope">
<!-- 此处加入自定义命令 v-loadmore-->
<el-table v-loading="dataListLoading" v-loadmore :row-key="scope.row.child.id" :data="scope.row.child" border style="width: 100%;" >
</el-table>
</template>
</el-table-column>
</el-table>
</template>
<script>
// 针对tabber懒加载的自定义指令
directives : {
loadmore : {
bind(el, binding,vnode) {
// 获取页面实例,为了可以调用定义的函数
let that = vnode.context
// 获取表格的Dom元素
const selectWrap = el.querySelector('.el-table__body-wrapper')
// 页面的滚动事件
document.addEventListener('scroll', function() {
let sign = 700
// 由于获取的是内嵌表格Dom,selectWrap.scrollTop获取不了数值
// 计算 表格实际高度 - 页面页面卷去的部分
const scrollDistance = selectWrap.scrollHeight - document.documentElement.scrollTop
// 判断表格剩余高度是否小于定义的触发值 由于浏览器兼容性差异 需做非负判断
if (scrollDistance <= sign && scrollDistance>0) {
// 触发定义的方法
that.loadMore()
}
})
}
}
},
methods:{
// tabber懒加载
loadMore(){
// 触发时请求下一页 并禁用页面滚动
document.documentElement.style.overflow='hidden';
if (this.timeout) {
clearTimeout(this.timeout)
}
// 防止页面滚动过快引发多次触发
this.timeout=setTimeout(() => {
this.BenefitsMealDetailPageReq.pageNum++
// 判断请求到的数据是否超过了总条数
if(this.dataRow.child.length < this.totalCount.totalCount) {
this.getTableList()
}else {
document.documentElement.style.overflow='';
}
}, 200);
}
}
</script>