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 分钟前
Vue3 Anime.js超级炫酷的网页动画库详解
开发语言·前端·javascript·vue.js·vue·ecmascript·vue3
霸道流氓气质1 小时前
Vue中使用vue-3d-model实现加载3D模型预览展示
前端·javascript·vue.js
追光的栗子2 小时前
vue3+vite 项目中怎么引入 elementplus 组件库
前端·vue.js·element
油丶酸萝卜别吃3 小时前
怎么判断一个对象是不是vue的实例
前端·javascript·vue.js
科技D人生3 小时前
Vue.js 学习总结(18)—— Vue 3.6.0-alpha1:性能“核弹“来袭,你的应用准备好“起飞“了吗?!
前端·vue.js·vue3·vue 3.6·vue3.6
泉城老铁5 小时前
Spring Boot + Vue 实现 DeepSeek 对话效果详细步骤
前端·vue.js·后端
sunbyte5 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | NotesApp(便签笔记组件)
前端·javascript·css·vue.js·笔记·tailwindcss
Face5 小时前
Vue源码解析(叁)
前端·vue.js
江城开朗的豌豆7 小时前
Event Bus:Vue组件间的'广播电台',轻松实现跨组件通信!
前端·javascript·vue.js
江城开朗的豌豆7 小时前
插槽:Vue里的‘占位符’,让组件更灵活!
前端·javascript·vue.js