持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
本文以 elmentUI 的 el-table 表格为例实现以下需求:
- 当多级嵌套表格的表头不一致时
- 还要使用懒加载
- 在一行展开时重新发请求,关闭时不发
elment自带的方法将无法实现,本文就提供了解决的办法
效果展示
由演示图可以看到,点击一行展开时,只有当前行会出现loading效果,表示只有当前展开的这一行发请求了
完整代码
- 给一级el-table设置 row-key="id" 用于判断是当前点击行展开,发请求
- 给一级el-table设置 @expand-change="getNew" 行展开或者关闭时触发函数 getNew()
- 给一级el-table的第一列设置 type="expand 和
<template v-slot="{row}"></template>
包裹 - 给二级el-table设置 :data="row.children" 和 v-loading="row.loading"
- getNew(row, expanded) 函数
- row 代表当前展开或关闭行,是一个对象
- expanded 代表当前所有展开行,是一个数组(里面是对象)
- JSON.stringify(expanded).includes(JSON.stringify(row)) 判断当前行是否已经展开,为 true 代表点击将当前行展开;为 false 代表点击将当前行关闭
- item.id === row.id 判断找到当前展开的行,把获取到的数据赋值进去
- 实现只有当前点击的展开行出现loading时,使用 this.$set( target , key , value)
- target: 要更改的数据源(可以是一个对象或者数组)
- key:要更改的具体数据 (索引)
- value:重新赋的值
<template>
<div>
<el-table
:data="tableData"
style="width: 100%;margin-bottom: 20px;"
@expand-change="getNew"
row-key="id"
>
<el-table-column type="expand">
<template v-slot="{row}">
<el-table
border
:data="row.children"
v-loading="row.loading"
>
<el-table-column prop="date" label="时间" width="180" />
<el-table-column prop="username" label="姓名" width="180" />
<el-table-column prop="address" label="住址" width="180" />
</el-table>
</template>
</el-table-column>
<el-table-column prop="age" label="年龄" width="180" />
<el-table-column prop="name" label="姓名" width="180" />
<el-table-column prop="gender" label="性别" width="180" />
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
// 一级表格的数据
tableData: [{
id: "1",
name: "张三",
age: 18,
gender: "男",
},
{
id: "2",
name: "李四",
age: 19,
gender: "男",
},
{
id: "3",
name: "王五",
age: 20,
gender: "男",
},
{
id: "4",
name: "男子",
age: 21,
gender: "男",
}],
// 模拟二级表格的数据,这里的数据再真实环境中是通过当前展开一级表格行的数据 发请求获得的
children1: [
{
id: '5',
address: '翻斗花园21号',
date: "2016-05-01",
username: "wangxiaohu",
}
],
}
},
methods: {
getNew(row, expanded){
console.log(row,expanded) // 当前行 当前已展开行
// 判断让当前行展开
if(JSON.stringify(expanded).includes(JSON.stringify(row)) === true){
this.$set(row, 'loading', true) // 表格加载开
this.tableData.forEach(item => {
// 找到当前展开的行,把获取到的数据赋值进去
if(item.id === row.id) {
console.log('id', item.id, row.id) // 可能打印四种 11 22 33 44
item.children = this.children1 || []
}
})
// 用定时器模拟发请求的延时过程
setTimeout(() => {
this.$set(row, 'loading', false) // 表格加载关
}, 500)
} else { // 让当前行关闭
delete row.children // 删除当前关闭行的 children
this.$set(row, 'loading', false) // 表格加载关
delete row.loading // 删除当前关闭行的 loading
}
},
},
}
</script>
总结:以上的完整代码可以直接复制到 vue 文件中查看效果,此代码没有用接口和数据交互,只是给大家提供一个思路,有经验的开发人员自己去在真实项目中实现吧