el-tree懒加载回显数据

简介: el-tree懒加载回显数据

el-tree懒加载回显数据

描述

懒加载回显,需要两个数据

1、你展开的节点key数组
2、你勾选的节点key数组

- key可以是id,这个在el-tree绑定

- 将这两个数据在保存的时候传给后端

- 点击编辑时,让后端返回对应的这两个数据

- 通过default-checked-keys回显勾选

- 通过default-expanded-keys回显展开过的节点

image.png

dom
<el-tree
  ref="tree"
  :data="treeData"
  :load="loadnode"
  :lazy="isLazy"
  check-on-click-node
  check-strictly
  :props="defaultProps"
  show-checkbox
  node-key="nodeId"
  @node-expand="keepExpandedNode"
  @check-change="hChangeTree" 
  @check="handleCheckChange"
  :default-expanded-keys="defaultExpandedNodes"
  :default-checked-keys="defaultCheckedNodes"
></el-tree>
保存展开过的节点数组,保存选中的节点数组
//保存展开过的节点
    keepExpandedNode(nodeData, node, tree) {
   
        let newFlag = this.expandedNodes.every(item => {
   
            return item.nodeId !== nodeData.nodeId
        });
        if (newFlag && !nodeData.isLeaf) {
   
            this.expandedNodes.push(this.cloneObj(nodeData))
        }
    },
    //点击多选框->整理已选选项并保存
    handleCheckChange(node, tree) {
   
      let list = this.cloneObj(tree.checkedNodes);  //tree.checkedNodes-未展开过的节点的子节点无法获取到
      list = list.filter(mItem => {
   
          return this.expandedNodes.every(item => {
   
              return item.nodeId !== mItem.nodeId
          })
      });
      this.value = list;
    },
    //深度复制对象
    cloneObj(obj) {
   
        let newObj = {
   };
        if (typeof obj === "object") {
   
            if (obj instanceof Array) {
   
                newObj = [];
            }
            for (var key in obj) {
   
                let val = obj[key];
                newObj[key] =
                    typeof val === "object" ? this.cloneObj(val) : val;
            }
            return newObj;
        } else {
   
            return obj;
        }
    },
data
data() {
   
   return {
   
     expandedNodes: [],  // 已经展开过的节点(拿到过下级的节点)
     value: [], // 已选节点
     defaultCheckedNodes: [], // 最终要回显的勾选key数组
     defaultExpandedNodes: [], // 最终要回显的展开过的key数组
     openList: [], // 后端返回的展开节点数据(需要处理成key数组)
     choliceList: [], // 后端返回的勾选节点数据(需要处理成key数组)
     meaningExpandedNum: 0, // 标的
   }
}
watch里监听

(非必需,我这里是因为后端返回数据结构问题,所以需要转化)

expandArr: {
   
      handler(newV, oldV) {
   
        if(newV){
   
          this.$nextTick(() => {
   
            this.openList = newV.split(',')
            // console.log(this.openList);
          })
          // console.log(this.defaultExpandedNodes);
        }
      },
      immediate: true,
    }, 
    selectArr: {
   
      handler(newV, oldV) {
   
        if(newV){
   
          this.$nextTick(() => {
   
            this.choliceList = newV.split(',')
          })
          // console.log(this.defaultCheckedNodes);
        }
      },
      immediate: true,
    },
回显
   async gettreeData(i, p, search) {
     // 获取tree数据
      const res = await getTreeData({
   
        level: i,
        parentId: p,
      });
      if(i == 1){
   
        this.firstTreeData = res.data.content
      }
      return res.data.content;
    },

    async loadnode(node, resolve) {
     // tree懒加载
      if (node.level == 0) {
   
        /// 如果需要多次回填,该初始化必需
        this.meaningExpandedNum = 0;
        this.defaultCheckedNodes = [];

        /// 回填展开节点
        this.$nextTick(()=>{
   
          this.defaultExpandedNodes = this.openList
        })

        setTimeout(async() => {
   
          let list = await this.gettreeData(1, "root");
          resolve(list);

          /// 注意回填要在树渲染后才生效
            this.$nextTick(() => {
   
            /// 没展开过节点,则直接在根节点层级回填
                if (0 === this.defaultExpandedNodes.length) {
   
                    this.defaultCheckedNodes = this.choliceList.map(item => {
   
                        return item
                    });
                }
            });
        },500)
      } else {
   
        let search = this.searchVal;
        this.gettreeData(node.level + 1, node.data.nodeId,).then(
          (res) => {
   
            if (res) {
   
              setTimeout(() => {
   
                resolve(res);

                /// 已选节点变成展开节点时、选值自动替换为下层节点;这是为了下次回填做的准备,回填过程中用不到
                if(node.checked){
   
                  let list = this.$refs.tree.getCheckedNodes();
                  list = list.filter(mItem => {
   
                      return this.expandedNodes.every(item => {
   
                          return item.nodeId !== mItem.nodeId
                      })
                  })
                  this.value = list;
                }

                /// 回填时保证在全部渲染后再回填
                this.meaningExpandedNum++;

                if (this.meaningExpandedNum === this.defaultExpandedNodes.length) {
   
                /// 回填复选框
                    this.defaultCheckedNodes = this.choliceList
                }
              }, 200);
            } else {
   
              return resolve([]);
            }
          }
        );

      }
    },
保存时将展开过的节点和勾选过的节点传给后端

我这里是因为组件封装有些多,所以需要将数据保存到vuex,最后再传给后端。

async hChangeTree(node) {
   
      let cholice = this.$refs.tree.getCheckedNodes()
      let choliceArr = [];
      cholice.forEach((item)=>{
   
        choliceArr.push(item.entityId)
      })
      // console.log(choliceArr);
      this.$store.commit("uploadCholiceNodeG",choliceArr)
      // 保存展开tree节点和勾选tree节点数据
}
遇到问题

懒加载回显,获取节点时,同时调用好几个接口,造成先padding,后500的bug,修复如下:

请求时参数正常,先padding,后500bug

参考

elementUI-Tree-懒加载树的选中与回填

目录
相关文章
|
6月前
【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。
【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。
element el-cascader动态编辑赋值后,不回显的解决方法(整理)
element el-cascader动态编辑赋值后,不回显的解决方法(整理)
|
前端开发
el-transfer 数据量过大加载慢卡顿解决办法:el-transfer虚拟滚动懒加载的实现
el-transfer 数据量过大加载慢卡顿解决办法:el-transfer虚拟滚动懒加载的实现
605 0
|
1月前
|
前端开发 JavaScript 开发者
利用 el-select 和 el-tree 实现树形结构多选框联动功能
本文详细介绍了如何使用ElementUI中的el-select下拉选择器和el-tree树形控件来实现多功能联动选择器,包括多选、删除、搜索、清空选项等功能。通过树形控件展示复杂的层级结构,用户可以通过下拉选择树形节点,实时搜索节点,且支持批量选择和删除功能。文中提供了完整的HTML、JavaScript和CSS代码实现,帮助开发者快速集成此功能。
379 0
利用 el-select 和 el-tree 实现树形结构多选框联动功能
|
3月前
|
前端开发 虚拟化
简单记录使用 ElementPlus 的虚拟化树形控件(el-tree-v2)心得
这篇文章分享了作者使用ElementPlus的虚拟化树形控件`el-tree-v2`的心得,展示了其基本用法和如何通过自定义模板来增强树节点的交互性。
1196 1
简单记录使用 ElementPlus 的虚拟化树形控件(el-tree-v2)心得
|
4月前
|
存储
el-tree 动态指定默认选中节点
el-tree 动态指定默认选中节点
354 6
|
4月前
【el-cascader-plus亲测有限】el-cascader级联选择器懒加载+多选功能回显失败解决方案
【el-cascader-plus亲测有限】el-cascader级联选择器懒加载+多选功能回显失败解决方案
177 0
|
6月前
|
移动开发 前端开发
vue3 Element-Plus封装的el-tree-select的使用
vue3 Element-Plus封装的el-tree-select的使用
404 0
vue3 Element-Plus封装的el-tree-select的使用
|
6月前
|
JavaScript
vue3使用element-plus 树组件(el-tree)数据回显
vue3使用element-plus 树组件(el-tree)数据回显
399 0
|
算法 JavaScript 测试技术
vue3源码分析——实现element属性更新,child更新
在上面流程图中,如果在setup中有一个对象obj,并且赋值为 ref({a:1}),然后通过某种方式重新赋值为2,就会触发更新流程;
vue3源码分析——实现element属性更新,child更新