Vue3 el-tree-v2渲染慢的问题

一、现象

使用el-tree-v2处理组织架构权限时,整个树的数据在8500条,勾选数据8200条,打开页面需要8~10秒,用户无法接受。 经调试,发现主要卡在树的渲染回显上(勾选数据少时,很快,勾选数据越多越慢)。

原始代码如下:

 <el-tree-v2 highlight-current ref="treeRef" node-key="orgNo" :data="orgOptions" :width="600" :height="380"
              :props="props" show-checkbox />

//取得后端数据后进行勾选
proxy.$nextTick(() => {
        proxy.$refs.treeRef.setCheckedKeys([]);        
        proxy.$refs.treeRef.setCheckedKeys(checkedKeys.value);     
      });

二、解决方法

1.设置属性:check-strictly,如下

<el-tree-v2 highlight-current ref="treeRef" node-key="orgNo" :data="orgOptions" :width="600" :height="380"
             :props="props" show-checkbox :check-strictly="checkStrictly" />
  
const checkStrictly = ref(false);           

2.在取回后端数据时,处理checkStrictly
处理逻辑:

  1. 先设置树为严格模式(不联动)
  2. 记录选中的条数
  3. 设置树的选中状态(不联动,速度很快)
  4. 最后一条时,恢复树联动状态
  5. 延时处理最后一条(会自动刷新整个树的勾选状态)

代码如下:

 let checkedIndexs = [];
 //设置严格模式,即上下级不联动
 checkStrictly.value = true; 
 //测试数据基本在100毫秒内处理完
 proxy.$nextTick(() => {
        proxy.$refs.treeRef.setCheckedKeys([]);
        let count = checkedKeys.value.length;//此为选中的数据
        //遍历数据,设置复选框状态
        for (let index = 0; index < count; index++) {
          //最后一行时,取消严格模式,即上下级联动
          if (index >= count - 1) {
            checkedIndexs.push(index);
            checkStrictly.value = false;
          }
          proxy.$refs.treeRef.setChecked(checkedKeys.value[index], true);
        }

      });

//延时处理,最后一行,联动状态
setTimeout(() => {
      checkedIndexs.forEach(element => {
        proxy.$refs.treeRef.setChecked(checkedKeys.value[element], true);
      });
    }, 200); //测试数据100毫秒执行完上面的遍历,安全起见,再预留100毫秒

3.效果
经过在上面的处理后,用户基本无感,整个回显处理不过300毫秒。

ps:
这个问题折腾了很久,网上也有说懒加载什么的,也尝试更换别的控件。最后发现是联动处理时,会遍历整个树,造成性能低下。所以,在开始时,取消联动处理(即不遍历树的关系),最后一条数据才处理联动(上级勾选/半勾选),整个树能秒出。

### Vue 中实现 el-tree-v2 的阶梯式显示并添加节点按钮 el-tree-v2Element Plus 社区中的一个增强版树组件,支持更灵活的自定义功能。为了实现在 Vue 中通过 el-tree-v2 组件创建具有阶梯式显示效果的树结构,并在每个节点上添加用于新增子节点的按钮,可以按照以下方式构建。 #### 数据模型设计 在 ViewModel 设计中,`ViewModel` 负责 `View` 和 `Model` 之间的信息传递[^1]。因此,在此场景下,数据模型应包含树形结构以及操作方法: ```javascript const treeData = ref([ { id: 1, label: &#39;Node 1&#39;, children: [ { id: 2, label: &#39;Child Node 1&#39; }, { id: 3, label: &#39;Child Node 2&#39;, children: [] } ] }, { id: 4, label: &#39;Node 2&#39;, children: [] } ]); ``` 上述代码展示了初始树的数据结构,其中每个节点都可能拥有自己的子节点列表 (`children`)。 #### 自定义渲染函数 el-tree-v2 支持通过插槽来自定义节点的内容。可以通过 `default-slots` 插入额外的操作按钮到每一个节点旁边。 以下是完整的示例代码片段: ```vue <template> <div class="tree-container"> <!-- 使用 el-tree-v2 --> <el-tree-v2 :data="treeData" node-key="id"> <!-- 定义默认插槽来定制化节点内容 --> <template #default="{ data }"> <span>{{ data.label }}</span> <!-- 显示节点名称 --> <!-- 添加按钮 --> <button @click.stop="addNode(data)">+</button> </template> </el-tree-v2> </div> </template> <script setup> import { ref } from &#39;vue&#39;; // 初始化树状数据 const treeData = ref([ { id: 1, label: &#39;Node 1&#39;, children: [{ id: 2, label: &#39;Child Node 1&#39; }, { id: 3, label: &#39;Child Node 2&#39;, children: [] }] }, { id: 4, label: &#39;Node 2&#39;, children: [] } ]); // 新增节点的方法 function addNode(node) { const newId = Date.now(); // 创建唯一ID const newNode = { id: newId, label: `New Child ${newId}`, children: [] }; if (!node.children) { Vue.set(node, &#39;children&#39;, []); } node.children.push(newNode); } </script> <style scoped> .tree-container button { margin-left: 8px; } </style> ``` 以上代码实现了如下功能: - **动态生成新节点**:当点击某个节点旁边的加号按钮时,会向该节点的子节点数组中追加一个新的对象。 - **防止事件冒泡干扰选中逻辑**:使用 `@click.stop` 来阻止点击按钮触发父级元素的选择行为。 #### 关键点解析 1. **Tree Data Structure**: 树形数据是一个嵌套的对象集合,每一层都可以有多个子节点。 2. **Custom Slot Usage**: 利用 `el-tree-v2` 提供的 slot 功能,可以在每个节点后面附加任意 HTML 元素(这里是按钮)。 3. **Reactivity Handling**: 对于响应式的修改,如果目标对象本身不存在某些属性,则需显式设置这些字段以确保其可被观察到。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值