element plus 的树形控件,如何根据后台返回的节点key数组,获取节点key对应的node节点

在使用 Element Plus 的 el-tree 组件时,如果后端返回的节点 key 数组中包含了部分选中的父级节点的 key,可能会导致该父级节点下的所有子节点也被默认选中。这是因为 el-tree 的默认行为是:如果一个父节点被选中,那么其所有子节点也会被选中。

为了解决这个问题,你需要在设置默认选中项时,手动检查每个节点的状态,确保只有指定的节点被选中,而其父节点和未指定的子节点不会被错误地选中。

以下是详细的解决方案和代码示例:

解决方案步骤

  1. 获取树形控件的引用 :通过 ref 获取 el-tree 实例,以便调用其方法。
  2. 处理后端返回的 key 数组 :遍历 key 数组,逐个设置节点的选中状态。
  3. 手动设置节点的选中状态 :使用 setChecked 方法为每个节点单独设置选中状态,而不是依赖 default-checked-keys 属性。这可以避免父节点被自动选中导致子节点全部选中的问题。
  4. 确保数据加载完成后再设置选中状态:如果树形控件的数据是异步加载的,确保在数据加载完成后再进行选中状态的设置。

详细代码示例

javascript 复制代码
<template>
  <div>
    <!-- 树形控件 -->
    <el-tree
      ref="tree"
      :data="treeData"
      :props="defaultProps"
      node-key="id"
      show-checkbox
      default-expand-all
      @check="onCheckChange"
    ></el-tree>

    <!-- 按钮触发设置默认选中 -->
    <button @click="setDefaultCheckedKeys">设置默认选中</button>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted } from 'vue';
import { ElTree, ElMessage } from 'element-plus';

export default defineComponent({
  components: {
    ElTree
  },
  setup() {
    // 树形控件的引用
    const tree = ref(null);

    // 树形控件的数据(假设从后端获取)
    const treeData = ref([
      {
        id: 1,
        label: '一级 1',
        children: [
          { id: 4, label: '二级 1-1', children: [{ id: 9, label: '三级 1-1-1' }] },
          { id: 5, label: '二级 1-2' }
        ]
      },
      {
        id: 2,
        label: '一级 2',
        children: [{ id: 6, label: '二级 2-1' }]
      },
      { id: 3, label: '一级 3', children: [] }
    ]);

    // 树形控件的配置
    const defaultProps = {
      children: 'children',
      label: 'label'
    };

    // 后端返回的节点 key 数组(包含部分选中的父级节点)
    const backendCheckedKeys = [1, 4, 6]; // 例如:选中了一级 1、二级 1-1 和二级 2-1

    // 存储最终需要选中的节点 key
    const finalCheckedKeys = ref([]);

    // 监听树形控件的选中变化(可选,用于调试或进一步处理)
    const onCheckChange = (checkedKeys, checkedNodes, halfCheckedKeys, halfCheckedNodes) => {
      console.log('选中的 keys:', checkedKeys);
      console.log('半选中的 keys:', halfCheckedKeys);
    };

    // 设置默认选中项的方法
    const setDefaultCheckedKeys = () => {
      if (!tree.value) {
        ElMessage.error('树形控件未加载完成');
        return;
      }

      // 清空之前的选中状态
      tree.value.setCheckedKeys([]);

      // 遍历后端返回的 key 数组,逐个设置选中状态
      backendCheckedKeys.forEach(key => {
        const node = tree.value.getNode(key);
        if (node) {
          // 仅选中当前节点,不影响父节点和子节点
          node.setChecked(true, false); // 第二个参数为 false,表示不改变子节点的选中状态
          finalCheckedKeys.value.push(key); // 记录最终选中的 key
          ElMessage.success(`节点 ${node.label} 已选中`);
        } else {
          ElMessage.error(`未找到 key 为 ${key} 的节点`);
        }
      });
    };

    // 确保在树形控件数据加载完成后再设置选中状态
    onMounted(() => {
      // 如果数据是异步加载的,可以在这里调用 setDefaultCheckedKeys
      // 例如,通过 API 请求获取数据后调用
      setDefaultCheckedKeys();
    });

    return {
      tree,
      treeData,
      defaultProps,
      setDefaultCheckedKeys,
      onCheckChange,
      finalCheckedKeys
    };
  }
});
</script>

代码解析

  1. 模板部分 (<template>)

    • el-tree 组件设置了 ref="tree",用于后续获取树形控件的实例。
    • node-key="id" 指定了每个节点的唯一标识符为 id
    • show-checkbox 显示复选框。
    • default-expand-all 默认展开所有节点。
    • 一个按钮用于触发设置默认选中项的操作。
  2. 脚本部分 (<script>)

    • 数据定义
      • treeData:树形控件的数据结构,通常从后端获取。这里为了示例,直接在前端定义。
      • defaultProps:配置树形控件的属性映射。
      • backendCheckedKeys:模拟后端返回的需要默认选中的节点 key 数组。注意,这个数组中包含了父级节点的 key(如 1),但只希望部分子节点被选中。
    • 方法定义
      • setDefaultCheckedKeys:主要方法,用于根据 backendCheckedKeys 设置默认选中项。它通过遍历 backendCheckedKeys,使用 getNode 方法获取对应的节点对象,然后调用 setChecked(true, false) 来仅选中当前节点,而不改变其子节点的选中状态。这样可以避免父节点被选中导致所有子节点被选中的问题。
      • onCheckChange:可选的监听器,用于监听树形控件的选中状态变化,便于调试或进一步处理。
    • 生命周期钩子
      • onMounted:确保在组件挂载后调用 setDefaultCheckedKeys,特别是在数据是异步加载的情况下。
    • 响应式变量
      • finalCheckedKeys:用于记录最终被选中的节点 key,可以在其他地方使用或展示。
  3. 关键逻辑

    • 避免父节点被自动选中 :通过调用 node.setChecked(true, false),仅将当前节点设置为选中状态,而不影响其子节点。这意味着即使某个父节点在 backendCheckedKeys 中,也只会选中该节点本身,而不会递归选中其所有子节点。
    • 清空之前的选中状态 :在设置新的默认选中项之前,先调用 tree.value.setCheckedKeys([]) 清空所有选中状态,确保不会有残留的选中项影响结果。
    • 错误处理 :如果某个 key 没有对应的节点,会通过 ElMessage.error 提示用户。

运行效果

当点击"设置默认选中"按钮时,树形控件会根据 backendCheckedKeys 数组中的 key 设置相应的节点为选中状态。由于使用了 setChecked(true, false),只有指定的节点会被选中,而其父节点和未指定的子节点不会被错误地选中。例如:

  • 如果 backendCheckedKeys 包含 1(一级 1)、4(二级 1-1)和 6(二级 2-1):
    • 一级 1 会被选中,但其子节点(如二级 1-2)不会被选中。
    • 二级 1-1 会被选中,且其子节点(如三级 1-1-1)不会被选中。
    • 二级 2-1 会被选中。

注意事项

  1. 确保 node-key 唯一node-key 属性指定的字段值必须在树形控件中是唯一的,否则可能导致意外的行为。
  2. 异步数据加载 :如果树形控件的数据是通过异步请求获取的,确保在数据加载完成后再调用 setDefaultCheckedKeys。可以通过监听数据加载完成的事件或使用 this.$nextTick 来实现。
  3. 性能优化 :对于非常大的树形控件,频繁调用 getNodesetChecked 可能会影响性能。可以考虑优化数据结构或减少不必要的操作。
  4. 用户体验:在实际应用中,可能需要更复杂的逻辑来处理用户的交互,例如允许用户手动选择或取消选择某些节点,同时保持默认选中的逻辑。根据具体需求进行调整。

通过以上方法,你可以精确地控制树形控件中哪些节点被默认选中,避免因父节点被选中而导致所有子节点被错误地选中的问题。

相关推荐
胡志辉的博客1 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖1 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty2 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚2 小时前
软件测试期末考试
vue.js
小二·2 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜3 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain5093 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年2754 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax
拉勾科研工作室5 小时前
区块链工程毕业论文题目【249个】
开发语言·javascript
小林ixn5 小时前
你以为你懂 + 号?看完这篇 Bun + TS 实战,才发现以前全写错了
前端·javascript·typescript