el-tree 组件选中数据状态

在使用 el-tree 组件时,初始有一份完整的数据和已选中的数据,经过一系列操作后,需要知道:

  • 用户最终选择了哪些数据(最终选中项)
  • 用户取消了哪些数据(最终未选中项)
  • 用户新增了哪些数据(新选中项 = 之前没选,现在选了)
  • 用户删除了哪些数据(删除项 = 之前选,现在没选了)

场景举例:

  • 初始化时:所有数据 allData,已选数据 selectedData
  • 用户操作后:最终选中数据 finalSelectedData

你要:

  • 新增项:finalSelectedData 相比于 selectedData 增加了什么
  • 删除项:selectedData 相比于 finalSelectedData 少了什么

如何实现

  1. 初始化时记录已选数据(比如用 selectedData 数组存放每个节点的 id)
  2. 操作后记录最终选中数据(比如用 finalSelectedData 数组存放每个节点的 id)
  3. 计算新增和删除数据:
js 复制代码
// setA - setB:A里有但B里没有
function arrayDiff(arrA, arrB) {
  return arrA.filter(item => !arrB.includes(item));
}

const addData = arrayDiff(finalSelectedData, selectedData);     // 新增:最终选中但原来没选
const deleteData = arrayDiff(selectedData, finalSelectedData);  // 删除:原来有但最终没选

el-tree 获取选中节点

一般你会用 this.$refs.tree.getCheckedKeys() 获取当前选中的节点 id 数组。

js 复制代码
// 初始化
const selectedData = [1, 2, 3]; // 初始已选 id

// 用户操作后
const finalSelectedData = this.$refs.tree.getCheckedKeys(); // 最终已选 id

// 计算
const addData = arrayDiff(finalSelectedData, selectedData);
const deleteData = arrayDiff(selectedData, finalSelectedData);

提交接口时

  • 新增项 addData 用于调用 add_data 接口
  • 删除项 deleteData 用于调用 delete_data 接口

示例代码

下面是 Ant Design Vue 的 Tree 组件实现,包含:

  • 显示所有树节点并初始化已选中
  • 用户操作后,计算新增和删除项
  • 提交时分别调用 add_datadelete_data 接口

假设你用的是 Vue 3 和 ant-design-vue@4.x


vue 复制代码
<template>
  <div>
    <a-tree
      checkable
      :tree-data="treeData"
      :checked-keys="checkedKeys"
      @check="onCheck"
      defaultExpandAll
    />
    <a-button type="primary" @click="handleSubmit" style="margin-top: 16px">
      提交变更
    </a-button>
    <div style="margin-top: 16px">
      <b>当前选中节点:</b> {{ checkedKeys.join(', ') }}
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { message } from "ant-design-vue";

// 所有树节点
const treeData = [
  {
    title: "Node1",
    key: "0-0",
    children: [
      { title: "Node1-1", key: "0-0-1" },
      { title: "Node1-2", key: "0-0-2" }
    ]
  },
  {
    title: "Node2",
    key: "0-1",
    children: [
      { title: "Node2-1", key: "0-1-1" }
    ]
  }
];

// 初始化已选中节点 key
const initialCheckedKeys = ["0-0-1", "0-1-1"];
const checkedKeys = ref([...initialCheckedKeys]); // 当前选中
const initialCheckedKeysRef = ref([...initialCheckedKeys]); // 用ref保存初始

// 选中变化
function onCheck(checkedKeysValue) {
  checkedKeys.value = checkedKeysValue;
}

// 计算数组差集
function arrayDiff(arrA, arrB) {
  return arrA.filter((item) => !arrB.includes(item));
}

// 提交接口
async function handleSubmit() {
  const addData = arrayDiff(checkedKeys.value, initialCheckedKeysRef.value);
  const deleteData = arrayDiff(initialCheckedKeysRef.value, checkedKeys.value);

  try {
    if (addData.length > 0) {
      await fetch("/api/add_data", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ keys: addData })
      });
      message.success("新增节点已提交:" + addData.join(", "));
    }

    if (deleteData.length > 0) {
      await fetch("/api/delete_data", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ keys: deleteData })
      });
      message.success("删除节点已提交:" + deleteData.join(", "));
    }

    if (addData.length === 0 && deleteData.length === 0) {
      message.info("没有变更,无需提交。");
    }
  } catch (e) {
    message.error("接口调用失败!");
  }
}
</script>

使用方法

  1. 安装依赖

    bash 复制代码
    npm install ant-design-vue
  2. main.js 里全局引入组件库(如未做过):

    js 复制代码
    import Antd from 'ant-design-vue'
    import 'ant-design-vue/dist/antd.css'
    app.use(Antd)
  3. 将上面代码保存为 AntdTreeExample.vue,并在你的页面引用即可。

  4. 修改接口地址 /api/add_data/api/delete_data 为你的实际接口。

相关推荐
hpoenixf2 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特2 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷3 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian3 小时前
前端node常用配置
前端
华洛4 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq4 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A5 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常5 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端
小码哥_常5 小时前
从Groovy到KTS:Android Gradle脚本的华丽转身
前端
灵感__idea5 小时前
Hello 算法:复杂问题的应对策略
前端·javascript·算法