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_data 和 delete_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 为你的实际接口。

相关推荐
lovingsoft25 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly35 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝39 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦39 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡1 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI1 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95271 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人1 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
内存过载1 小时前
用表格模拟甘特图:项目排期的土办法
前端·低代码
葡萄城技术团队2 小时前
用 SpreadJS 数据验证实现省市区三级联动
前端