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的对象,触发的时候也是用父节点去触发。

相关推荐
Roye_ack3 小时前
【项目实战 Day9】springboot + vue 苍穹外卖系统(用户端订单模块 + 商家端订单管理模块 完结)
java·vue.js·spring boot·后端·mybatis
北城以北88885 小时前
Vue--Vue基础(二)
前端·javascript·vue.js
FuckPatience7 小时前
Vue 组件定义模板,集合v-for生成界面
前端·javascript·vue.js
有梦想的攻城狮8 小时前
从0开始学vue:vue和react的比较
前端·vue.js·react.js
silent_missile10 小时前
vue3父组件和子组件之间传递数据
前端·javascript·vue.js
JIngJaneIL12 小时前
图书馆自习室|基于SSM的图书馆自习室座位预约小程序设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·图书馆自习室
koooo~14 小时前
Vue3中的依赖注入
前端·javascript·vue.js
java水泥工15 小时前
网上摄影工作室|基于SpringBoot和Vue的网上摄影工作室(源码+数据库+文档)
数据库·vue.js·spring boot
花花鱼15 小时前
vxe-grid在树形模式下通过$grid.getTableData().fullData无法获取到所有数据的简单处理
vue.js
Tachyon.xue17 小时前
Vue 3 项目集成 Element Plus + Tailwind CSS 详细教程
前端·css·vue.js