vue table 懒加载树形数据时,子节点数据刷新处理

树形数据加载很常用的功能,而且使用场景非常多,但子节点刷新确是个麻烦事

#树形数据分两种,后端接口天然支持树形。这种非常简单。

html 复制代码
<template>
    <div>
      <el-table :data="tableData" style="width: 100%;margin-bottom: 20px;" row-key="id" border default-expand-all
        :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
        <el-table-column prop="date" label="日期" sortable width="180">
        </el-table-column>
        <el-table-column prop="name" label="姓名" sortable width="180">
        </el-table-column>
        <el-table-column prop="address" label="地址">
        </el-table-column>
      </el-table>
  </template>
  <script>
    export default {
      data() {
        return {
          tableData: [{
            id: 1,
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            id: 2,
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            id: 3,
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄',
            children: [{
                id: 31,
                date: '2016-05-01',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1519 弄'
              }, {
                id: 32,
                date: '2016-05-01',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1519 弄'
            }]
          }, {
            id: 4,
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }],
      },
    }
}
</script>

正常数据量不大,直接接口就能把树形数据放回,万事大吉,刷新接口,即可完成子节点的刷新

前端页面需要懒加载,接口不支持

有些时候,接口是不可能把所有子节点的数据返回的,那么只能点击一个父级加载一个,而且懒加载,比较省资源。那么就必须要解决刷新的问题。

html 复制代码
<template>
    <div>
        <el-table :data="tableData1" style="width: 100%" row-key="id" border lazy :load="load" ref="table"
            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
            <el-table-column prop="date" label="日期" width="180">
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="180">
            </el-table-column>
            <el-table-column prop="address" label="地址">
            </el-table-column>
        </el-table>
    </div>
</template>
<script>
export default {
    data() {
        return {
            tableData1: [{
                id: 1,
                date: '2016-05-02',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1518 弄'
            }, {
                id: 2,
                date: '2016-05-04',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1517 弄'
            }, {
                id: 3,
                date: '2016-05-01',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1519 弄',
                hasChildren: true
            }, {
                id: 4,
                date: '2016-05-03',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1516 弄'
            }],
            maps: new Map()
        }
    },
    methods: {
        load(tree, treeNode, resolve) {
            getProjectWork({
                page: this.pageParam.page,
                size: this.pageParam.size,
                fid: tree.id,
            }).then((res) => {
                if (res.code == 0) {
                    if (!res.data.list.length) {
                        /*
                            element-ui中table懒加载数据时,如果data是空数组,则不会刷新
                            lazyTreeNodeMap中记录了懒加载节点的子列表数据
                            通过tree.id作为key,将数据存入lazyTreeNodeMap中,因此手动清除缓存数据即可
                        */
                        // 注意:要在el-table组件上绑定ref='table'
                        this.$set(this.$refs.table.store.states.lazyTreeNodeMap, tree.id, [])
                    } else {
                        resolve(res.data.list);
                    }
                    this.map.set(tree.id, { tree, treeNode, resolve });

                }
            });
        },
        // 触发刷新节点方法
        refresh(parentId) {
            // 根据父级id取出对应节点数据
            if (this.maps.get(parentId)) {
                const { tree, treeNode, resolve } = this.maps.get(parentId)
                if (tree) {
                    this.load(tree, treeNode, resolve)
                }
            }
        },
    },
}
</script>

正常配置

  1. 设置 Table 的 lazy 属性为 true
  2. 加载函数 load
  3. 指定 row 中的 hasChildren字段来指定哪些行是包含子节点

以上懒加载必备属性。

解决懒加载刷新

  1. 定义maps字段
js 复制代码
this.map.set(tree.id, { tree, treeNode, resolve });
  1. 每次点击打开父节点时,把参数存储下来。

直接在加载子节点属性的方法内补充

js 复制代码
 this.map.set(tree.id, { tree, treeNode, resolve });
  1. 重点,当数据为空时,需要手动处理
js 复制代码
this.$set(this.$refs.table.store.states.lazyTreeNodeMap, tree.id, [])
  1. 补充一个刷新的方法

此方法就是直接在请求一次加载子节点

js 复制代码
 refresh(parentId) {}

后面的工作就简单了

  1. 删除数据了,直接访问一下 refresh 方法
  2. 数据修改了,直接访问一下 refresh 方法
  3. 批量数据删除了,那就一个个去请求 refresh 方法

注意点:

maps 存储的是以父节点id为key的对象,触发的时候也是用父节点去触发。

相关推荐
萌萌哒草头将军7 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
ai产品老杨10 小时前
减少交通拥堵、提高效率、改善交通安全的智慧交通开源了。
前端·vue.js·算法·ecmascript·音视频
张老爷子11 小时前
记录uniapp开发安卓使用webRTC实现语音推送
vue.js
发渐稀12 小时前
vue项目引入tailwindcss
前端·javascript·vue.js
vanora111115 小时前
Vue在线预览excel、word、ppt等格式数据。
前端·javascript·vue.js
xiaogg367815 小时前
网站首页菜单顶部下拉上下布局以及可关闭标签页实现vue+elementui
javascript·vue.js·elementui
有梦想的攻城狮16 小时前
从0开始学vue:pnpm怎么安装
前端·javascript·vue.js
pzpcxy52016 小时前
安装VUE客户端@vue/cli报错警告npm WARN deprecated解决方法 无法将“vue”项识别为 cmdlet、函数
前端·vue.js·npm
白云~️18 小时前
table表格合并,循环渲染样式
javascript·vue.js·elementui
这可不简单18 小时前
方便易懂的自适应方案---echarts和dom样式大小自适应
前端·vue.js·echarts