持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
正常情况表格数据都是通过分页拿取对应页码的数据量展示到表格中,但如果是树结构,而且父节点下数据量又很多的情况下,就需要做出懒加载的树结构表格了,效果如下图所示
要做这个树结构表格懒加载的效果其实很容易,从ElementUI组件库中我们就可以找到类似的Demo。
load(tree, treeNode, resolve) {
setTimeout(() => { // 延迟,模拟接口
resolve([{id:1,name:"叶"}]) //将接口的数据包装成数组传入resolve
})
}
但从Demo中可以发现,展开节点时,会执行load的加载函数,把请求接口的数据做完resolve参数即可。但有个问题是展开后,再次展开并不会再次执行load函数,这就导致了当子节点数据更新了,但是却获取不到,达不到动态更新子节点的需求。
如下图,当我们在指定行点新增时,提示我们新增成功了,但如果用户不刷新页面,想必用户内心默默骂了一句“新增成功老子的数据呢???”
要解决这个问题也很简单,思路是: 借助一下Map,将load函数的对应参数存储起来,手动调用一次load即可。
Map的前置知识:
- 引用MDN文档的介绍:
Map对象保存键值对(key-value),并且能够记住Key的原始插入顺序。任何Value(对象或者原始值)都可以作为一个键或一个值。
- Map和Object其实有很多不同点,当然也有相似点
- 相似的是:Map和Object都允许咱们根据Kye存取一个value、删除Key、检测一个Key是否存在value。所以过去我们一直都把对象当成
Map使用。 - 不同的是:
- 1、
Key类型:Map的key可以是任意类型的数据,而Object的key只允许类型是String或Symbol。 - 2、
key名冲突:Map默认情况不包含任何key,只包含显示插入的key。而Object因为有原型的存在,因此原型链上的key可能会与咱们定义的key起冲突。 - 3、
获取数量:Map可以通过size属性,轻松的拿到key-value的个数。而Object则只能手动去计算key-value的个数
- 1、
-
Map和Object当然还有其他很多不同点,但与本文关系不大,这里就不展开说明了。这里借助Map是因为key是数字,当然你也可以将数字转成字符串,然后用Object,但我不,我就要用Map(手动狗头)。
- 相似的是:Map和Object都允许咱们根据Kye存取一个value、删除Key、检测一个Key是否存在value。所以过去我们一直都把对象当成
动态新增编辑子节点的步骤如下:
- 首先在data()中初始化一个Map对象 loadMap
data(){
return {
// 记录每个层级的懒加载函数参数
loadMap: new Map(),
}
}
2、在load函数的内首先将参数存为Map对象value,key则是请求接口需要使用的id值。
load(tree, treeNode, resolve) {
this.loadMap.set(id, { tree, treeNode, resolve })
xxxx...//编写其他逻辑
}
3、当我们新增成功后,从Map对象中取出指定的key的value,然后手动调用一次load,并把vakue作为参数传递给load即可
submitForm(formName) {
//提交成功后,执行以下两句代码即可达到动态更新
const { tree, treeNode, resolve } = this.loadMap.get(id)
this.load(tree, treeNode, resolve)
}
通过这一系列操作,你会发现终于可以动态更改子节点内的数据了,不再需要傻傻的刷新页面了。
可当你点击删除的时候
“tm的,不是已经解决动态更新了吗,怎么还是得刷新页面才能更新,呜呜呜呜呜呜呜”,想必你会有这种想法,别急,接下来就是解决删除后不能更新子节点数据的了。
删除跟新增和编辑还不太一样,需要额外多两步操作。
- 首先要在el-table标签内容定义一个:
ref="lazytable"
<el-table
v-loading="loading"
:data="tableData"
ref="lazytable"
row-key="projectId"
:load="load"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
....
</el-table>
- 删除时,通过ref获取到table节点,将指定节点下的子节点数据清除后,在手动调用一次load函数
handleDelete(){
...
const { tree, treeNode, resolve } = this.loadMap.get(row.parentId)
// 删除会更新的关键
this.$set(this.$refs.lazytable.store.states.lazyTreeNodeMap, row.parentId, []);
this.load(tree, treeNode, resolve)
...
}
至此,树结构懒加载就可以正常动态更新子节点,各位客官看完点个赞留个言吧