el-tree 折叠节点时去掉 defaultExpandedKeys 中已折叠的节点及其子节点

发布时间 2023-08-25 11:50:49作者: shayloyuki

问题场景

树形节点默认是全部折叠的。展开节点A,再把它折叠。然后给节点B新增子节点,新增成功后刷新树,却发现节点A是展开的。

原因分析

树刷新后全部节点都默认是折叠的,除非 defaultExpandedKeys 数组中有数据(这些节点数据是展开的)。

因此,只需要在折叠节点A时,在 defaultExpandedKeys 数组中移除掉节点A及其子节点数据即可。

image

节点展开和折叠触发的函数
/* 节点展开触发 */
handleNodeExpand(data, node) {
  // 保存当前展开的节点
  let flag = false;
  this.expandedList.some((ele) => {
    if (ele === data[this.nodeKey]) {
      // 判断当前节点是否存在,存在则不做处理
      flag = true;
      return true;
    }
  });

  if (!flag) {
    // 不存在则存到数组中
    this.expandedList.push(data[this.nodeKey]);
  }
},
/* 节点缩起触发:删除当前缩起的节点及其子节点 */
handleNodeCollapse(data) {
  // 数组扁平化
  const flatChildren = this.extractTree([data], "children").map(
    (ele) => ele[this.nodeKey]
  );
  // 遍历要移除的节点数组,如果在展开的节点数组中,则移除
  flatChildren.forEach((e) => {
    const index = this.expandedList.indexOf(e);
    if (index === -1) return;
    this.expandedList.splice(index, 1);
  });
},

注意

defaultExpandedKeys 数组中移除掉节点A及其子节点数据

如果是遍历 this.expandedList,检查 flatChildren 是否包含该元素,这样的实现方式会有 bug:

  1. this.expandedList 无法移除元素;
  2. 或者,若展开了节点A之后又展开节点A下的节点B,再折叠节点A:会导致无法折叠,并且 this.expandedList 只会移除节点A数据,不会移除节点B数据,除非再点击一次折叠节点A,才会发生折叠效果。

原因是:遍历 this.expandedList 的依据是 index,但是 this.expandedList 移除元素也是依靠 index,就会导致出错。

参考链接

优化用户体验:"解决 el-tree 刷新自动展开节点"