ElementUI 树形表格懒加载,内层数据实时更新问题|8月更文挑战

2,818 阅读3分钟

背景

这几天做需求,有一个表格是树形数据,内层的数据采用懒加载,但是在内层数据修改之后,UI页面的数据没有实时更新,感觉用户体验不是特别好,记录一下优化的过程。

采用的是ElementUI来实现的树形表格

需求描述

  1. 表格数据为树形数据(可以类比文件夹),内层数据采用懒加载
  2. 可以对文件夹进行增加,删除,重命名操作
  3. 若内层数据不为空,需要显示展开标志,点击展开标志加载内层数据

image.png

问题描述

  1. 在修改内层数据名称时,页面内层数据不能实时更新。因为提交修改之后,重新请求表格数据获取的只是最外层的数据,内层的数据因为懒加载,只会在展开的时候加载,所以并没有更新。

  2. 外层数据中有一个属性 isLeaf 来标记是否有内层数据。当把第三层数据删完时,第二层数据的isLeaf属性没有及时更新会继续显示展开图标,让人以为还有内层数据。第二层数据删完不会有这样的问题。因为删除之后,重新请求表格数据也是获取最外层的数据。

这两个问题的区别在于内层数据是否和外层数据有关联。本质上是因为操作表格后请求,表格数据获取的只是最外层的数据,内层的数据没有更新。怎么解决这个问题呢?有三个想法。

方法描述

1. 强制刷新组件

最容易想到的方法就是刷新页面了,但是这样页面会闪烁。 可以采用刷新组件的方法。 在操作完表格数据后,直接刷新整个表格组件,这样展开的数据会闭合,在之后展开的时候重新请求内层数据就可以实现视图层面的更新了。

这里就涉及到怎么刷新组件的问题,可以参考这篇文章 Vue 中 强制组件重新渲染的正确方法

这里采用的是更新组件的key值来刷新组件

只需要先给组件绑定key值

<template :key="componentKey"></template>

然后在数据更新的时候更新组件的key值就可以了

this.componentKey = this.componentKey === 0 ? 1 : 0;

组件的key值更新后,组件会刷新。

优点:无需增加存储空间,实现简单。

缺点:需要刷新组件,要考虑组件刷新的成本,刷新后会关闭内层数据,需要重新打开,用户体验稍次。

2. 利用内置的load函数

在内置提供的load函数中,用map把{ tree, treeNode, resolve }保存在data中,用keyid标记。 这样就可以把每一个数据专用的渲染内层数据的对象和方法保存到本地,方便之后调用。

//用于保存懒加载需要的内置用于渲染子节点的对象和方法
funcCache: new Map(),
this.maps.set(tree.keyid, { tree, treeNode, resolve });

在需要刷新内层数据的时候取出对象和方法进行操作

const { tree, treeNode, resolve } = this.funcCache.get(parentId);

优点:数据实时刷新,用户体验好。

缺点:需要存储大量对象,数据个数为N,存储的对象数量为大致为O(N)(大概这样理解一下),可能比较浪费存储空间。

在处理上述提到的第二个问题时,因为内层数据的操作可能导致外层数据的变化,所以只刷新内层数据是不够的,还要刷新外层数据,而且可能要回溯到被影响的最外层数据,这样逻辑就变得比较复杂了。

向大佬们求助

不知道大佬们有没有什么优化建议或者其它解决方案可以交流分享。

如果有这种需求的 “ 银弹 ” 也欢迎分享!