码农之家

el-table的树形表格懒加载

一、 前言

最近遇到一个树形表格结构的需求,在此之前我都是用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 作者:地霊殿__三無