解决vue+element-ui项目中表格树形结构子节点数据重新加载问题【项目中实践】

问题描述

element-ui中表格树形数据结构,使用了懒加载模式时,在对数据进行增删改查时视图并不能实时更新,需要刷新浏览器进行强制刷新数据才会显示。

解决方案

  • 百度+源码阅读
    在element-ui中的table文件中的tree.js文件中找到关于子节点懒加载的方法。
loadData(row, key, treeNode) {
      const { load } = this.table;
      const { lazyTreeNodeMap, treeData } = this.states;
      if (load && !treeData[key].loaded) {
        treeData[key].loading = true;
        load(row, treeNode, data => {
          if (!Array.isArray(data)) {
            throw new Error('[ElTable] data must be an array');
          }
          treeData[key].loading = false;
          treeData[key].loaded = true;
          treeData[key].expanded = true;
          if (data.length) {
            this.$set(lazyTreeNodeMap, key, data);
          }
          this.table.$emit('expand-change', row, true);
        });
      }
    }

从以上代码我们不难看出表格树形数据在每次更新节点时都调用了该方法。其中load就是组件暴露出来给我们绑定懒加载的方法。该方法中实现节点更新的关键代码在于this.$set(lazyTreeNodeMap, key, data);

this.$set(lazyTreeNodeMap, key, data);
lazyTreeNodeMap: this.$refs.table.store.states.lazyTreeNodeMap // table为组件中ref绑定属性
key: // 就是table-key,
data: // 节点的children数组

项目实践代码

html代码

<!-- 表格 -->
<el-table
	ref="multipleTable"
	:data="categoryList"
	style="width: 100%;margin-bottom: 20px;"
	lazy
	:load="loadTree"
	:indent="40"
	row-key="id"
	:default-expand-all="false"
	:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
	...
</el-table>

data代码

maps: new Map()

表格组件中load绑定的loadTree方法

loadTree(tree, treeNode, resolve) {
      // 将当前选中节点数据存储到map中
      this.maps.set(tree.id, { tree, treeNode, resolve })
      try {
      	// 根据实际项目发送ajax获取数据
        getGoodsCategorys({
          parentId: tree.id
        }).then(res => {
          const nodes = res.data.map(item => {
            return {
              ...item,
              // 该数据有三级结构
              hasChildren: item.level <= 2
            }
          })
          resolve(nodes)
        })
      } catch (error) {
        return error
      }
    }

触发loadTree方法

// 重新触发树形表格的loadTree函数(因项目中需要多次触发loadTree方法,故封装成一个方法)
refreshLoadTree(parentId) {
	// 根据父级id取出对应节点数据
	const { tree, treeNode, resolve } = this.maps.get(parentId)
	this.$set(this.$refs.multipleTable.store.states.lazyTreeNodeMap, parentId, [])
	if (tree) {
		this.loadTree(tree, treeNode, resolve)
	}
}

无论是对节点进行增加、修改、删除都是通过触发refreshLoadTree方法中的this.$set(this.$refs.multipleTable.store.states.lazyTreeNodeMap, parentId, [])+this.loadTree(tree, treeNode, resolve)进行更新节点数据的。

结束语:希望该文章能够帮助你在项目中该解决问题。如有更好的解决方法或是对该解决方案有疑问,欢迎留言一起讨论!

你可能感兴趣的:(10-element-ui,vue)