针对懒加载的树组件,节点数据发生变化后,只刷新局部数据,拿到最新的节点
antd tree提供的loadData属性,支持传入一个方法,用于异步加载子节点的数据。当某一节点的数据已经加载之后,收起节点再次展开是不会触发异步加载的方法的,因此节点数据不会刷新。需要我们手动变更一些值才能触发该方法。
首先要明确树组件触发懒加载的前提条件:
1. expandedKeys包含节点key值

2. loadedKeys不包含需要刷新的节点的key值,即此前未曾加载过

3. treeData中不包含该节点的children数据,即children=[]

只有以上三点同时满足,才会触发loadData方法。
A节点下新增子节点后,刷新A节点的子节点需要3步:
注意:A节点的所有子孙节点均需要回到收起状态,否则会多次调用接口加载已展开的节点数据
代码:
- // 获取当前节点id以及下面所有子孙节点的id
- getNodeAndChildrenIds (data) {
- let temp = [];
- const loop = (data) => {
- data.map(item => {
- temp.push(item.id)
- if (item.children && item.children.length) {
- loop(item.children);
- }
- })
- }
-
- loop(data);
- return temp;
- },
- // 更新树组件的数据
- updateTreeData(id) {
- const temp = _.cloneDeep(this.treeData);
- let node;
- const loopFn = (data, id) => {
- if (node) {
- return;
- }
- data.some((item) => {
- if (item.id === id) {
- node = _.cloneDeep(item.children);
- item.children = [];
- return true;
- }
- if (item.children && item.children.length) {
- loopFn(item.children, id);
- }
- });
- };
- // 获取A节点的子节点,并把A节点的children移除
- loopFn(temp, id);
- this.treeData = _.cloneDeep(temp);
- // 获取A节点下面所有子孙节点的id
- const nodeIds = this.getNodeAndChildrenIds(node);
- // loadedKeys中移除A节点的key
- let loadedKeys = _.cloneDeep(this.loadedKeys.filter(item => item !== id));
- // 去掉A下面已加载的子孙节点的key
- loadedKeys = _.cloneDeep(loadedKeys.filter(item => !nodeIds.includes(item)));
- this.loadedKeys = _.cloneDeep(loadedKeys);
- // 去掉A下面已展开的子孙节点id
- this.expandedKeys = _.cloneDeep(this.expandedKeys.filter(item =>
- !nodeIds.includes(item)));
- }
以上是刷新子节点的方法。
当A节点本身发生变更或删除时,则需要刷新A节点的数据,此时同样可以通过上面的方法。但是这里推荐另一种方式,即手动更新数据,不走接口,这种方式更为简单。
代码:
- /** 找到对应的节点执行某操作 */
- treeAction (node, id, fn) {
- node.some((item,index) => {
- if (item.id === id) {
- fn(node, item, index)
- return true;
- }
- if (item.children && item.children.length) {
- treeAction(item.children, id, fn);
- }
- });
- },
- // 删除树节点
- async deleteTreeNode(data) {
- await api.deleteFn(data.id);
- this.$message.success('删除成功!');
-
- // 手动删除A节点和其子孙节点
- treeAction(this.treeData, data.id, (node, item, index) => {
- node.splice(index, 1);
- });
- },
- // 重命名树节点
- async editTreeNode(data, form) {
- const params = {
- ...
- };
- await api.editFn(params);
- this.$message.success('重命名成功!');
-
- // 手动重置A节点名称
- treeAction(this.treeData, data.id, (node, item, index) => {
- item.name = form.name;
- });
- },