一、 前言
最近遇到一个树形表格结构的需求,在此之前我都是用el-table表格的基础用法,现在突然来了点不一样的需求,我寻思捣鼓捣鼓,踩踩坑的同时,也记录一下实现过程。
二、使用到的属性和方法事件
1、row-key
参数类型:String/function。
行数据的 Key,用来优化 Table 的渲染。
在使用 reserve-selection 功能与显示树形数据时,该属性是必填的。
类型为 String 时,支持多层访问:user.info.id
,但不支持 user.info[0].id
,此种情况请使用 Function
。
树形数据的时候,该属性必填,而且最好给数字或唯一属性,我就是第一次忘记填写这个属性,导致树形下拉出不来,我还琢磨了好久,下面几个属性都配置了,咋一点动静都没有。
2、lazy
是否懒加载子节点数据。
参数类型: Boolean。
3、load
参数类型:Function(row, treeNode, resolve)。
加载子节点数据的函数,lazy 为 true 时生效,函数第二个参数包含了节点的层级信息。
load 这个是动态添加数据的,前提是(lazy属性为true ,表格数组里设置了hasChildren:true)
注意:Table表格组件 树形结构数据懒加载load只会执行一次
4、tree-props
渲染嵌套数据的配置选项。
参数类型: object。
默认值: { hasChildren: ‘hasChildren’, children: ‘children’ }
treeprops 是配置树状收缩数据的
treeprops :{hasChildren} 是否可收缩,是否有下拉展开折叠小三角
treeprops :{children} 展开的子项,具体的内容显示
5、expand-change
当用户对某一行展开或者关闭的时候会触发该事件(展开行时,回调的第二个参数为 expandedRows;树形表格时第二参数为 expanded)。
函数自带参数有:row, (expandedRows | expanded)
今天我们要用的是树形表格,所以第二参数取expanded。
这个事件主要作用是用来动态刷新用的,因为load函数仅加载一次,如果表格内容发生变化,它并不能实时更新。
三、实现逻辑
1、配置本文第二节的属性和事件
row-key和tree-props里的children字段是必要。
如果是懒加载,那就需要加上lazy、load方法、以及tree-props里要有hasChildren字段,
hasChildren字段需要为boolean,将决定是否有下拉展开。
load方法仅会首次触发,后续我们用expand-change的方法,完成子节点的数据更新。
2、load方法
首次异步加载数据。
load(tree, treeNode, resolve) {
// 保存父级id,在你需要刷新子级数据的地方可以用到
this.currentParentId = tree.deviceId
// 在之前声明的全局变量中,增加一个key为 本条数据的id,id可替换为你数据中的任意唯一值
this.tableTreeRefreshTool[tree.deviceId] = {}
// 重要!保存resolve方法,以便后续使用
this.tableTreeRefreshTool[tree.deviceId].resolve = resolve
// 记录展开次数,具体作用后续介绍
this.tableTreeRefreshTool[tree.deviceId].expandCount = 0
// 请求api接口获取数据// 必须是异步
setTimeout(() => {
const arr = this.tableData.find(item => item.deviceId === tree.deviceId).childrenList
resolve(arr)
}, 1000)
}
3、handleExpandChange方法
用来每次打开收缩都刷新动态数据。
handleExpandChange(row, expanded) {
console.log(row, expanded, this.tableTreeRefreshTool)
if (Object.keys(row).length > 0) {
// 获取到之前保存的全局变量
const curr = this.tableTreeRefreshTool[row.deviceId]
// // 展开次数 +1
curr.expandCount++
// 如果是展开状态,且展开次数大于1,且上一次的状态为折叠,则请求api数据,不需要更新子菜单
if (expanded && curr.expandCount > 1 && !curr.prevStatus) {
// api请求// 必须是异步
setTimeout(() => {
const arr = this.tableData.find(item => item.deviceId === row.deviceId).childrenList
curr.resolve(arr)
}, 100)
}
// 保存本次的展开或折叠状态,用于下次判断
curr.prevStatus = expanded
}
}
4、表格查询时,触发更新
在getList函数里,获取完表格最新数据后,发现不会更新树形表格里已展开的部分,所以增加了以下逻辑。
通过每次都记录了已展开状态下row行,存储在变量tableTreeRefreshTool中,通过展开关闭的操作,达到更新最新数据的目的。
getList() {
// 获取表格数据逻辑......//
// 关闭当前展开,再展开,达到更新数据的目的
for (var x in this.tableTreeRefreshTool) {
var flag = this.tableData.findIndex(item => item.deviceId === x)
if (flag !== -1 && this.tableTreeRefreshTool[x].prevStatus) {
this.$refs.questionTable && this.$refs.questionTable.toggleRowExpansion(this.tableData[flag], false)
this.$refs.questionTable && this.$refs.questionTable.toggleRowExpansion(this.tableData[flag], true)
}
}
}
四、小结
本文先讲解了树形表格用到的属性和事件,随后带着jym们实现了简单的树形表格,jym可以也动手试试看。
ps: 我是地霊殿__三無,希望能帮到你。
原文链接:https://juejin.cn/post/7345757062108119092 作者:地霊殿__三無