Element@2.15.14-tree checkStrictly 状态实现父项联动子项,实现节点自定义编辑、新增、删除功能

背景:现在有一个新需求,需要借助树结构来实现词库的分类管理,树的节点是不同的分类,不同的分类可以有自己的词库,所以父子节点是互不影响的;同样为了选择的方便性,提出了新需求,选择了父级子级需要全选,父级取消勾选子级需要全部取消勾选;分类支持修改名称、增加子节点、删除子节点,多选子节点时需要获取当前所选分类下的所有词库。
一、开发前需要知道的
1、树结构需要借助 element 的 tree 组件
2、树结构需要设置父子级不关联,即 :check-strictly="true"
3、节点选择时如果是非叶子结点(最后一层的子节点,没有 children),需要递归获取子节点,如果进行节点的选择与取消选择
4、自定义节点需要通过 slot 方式活着 render-content 方式实现
二、实现流程
1、引入 tree,传入源数据 data、设置 key,设置默认配置属性 defaultProps
1. 定义 tree
<el-tree:check-strictly="true":data="data"@check-change="checkChange"ref="treeRef"show-checkboxdefault-expand-allnode-key="id"ref="tree"highlight-current:props="defaultProps"
>
</el-tree>
2. 设置 data
data = [{id: xx, label: xx, children: {id: number, label: string, children: []}[]}]
3. 设置父子不关联
:check-strictly="true"
4. 设置默认配置
const defaultProps = {children: "children",label: "label",
}
2、实现父子勾选子级联动
// 1. 给 el-tree 绑定 check-change 事情
@check-change="checkChange"// 2. 实现 checkChange 函数
// data:当前节点 checked:节点是否选中 indeterminate:是否有选中的子项
function checkChange(data, checked, indeterminate) {console.log("data, checked, indeterminate", data, checked, indeterminate);this.$nextTick(() => {// 2.1 获取节点详细信息const nodeInfo = this.$refs.treeRef.getNode(data.id);const { isLeaf, checked } = nodeInfo;this.nodeInfo = nodeInfo;function getAllIds(arr, res = []) {for (let i = 0; i < arr.length; i++) {res.push(arr[i].id);if (arr[i].children && arr[i].children.length) {getAllIds(arr[i].children, res);}}return res;}// 2.2 获取当前已选中的节点console.log(this.$refs.treeRef.getCheckedKeys());// 2.3 如果是父级,子级选中跟取消选择if (!isLeaf) {const checkedIds = this.$refs.treeRef.getCheckedKeys();const ids = getAllIds(nodeInfo.data.children);console.log(ids);// 2.3.1 父级选中,子级全选if (checked) {this.$refs.treeRef.setCheckedKeys(Array.from(new Set([...checkedIds, ...ids])));} else {// 2.3.2 父级取消选中,子级全不选this.$refs.treeRef.setCheckedKeys(Array.from(new Set(checkedIds.filter((item) => !ids.includes(item)))));}}});
},
3、通过 slot 实现编辑、新增、删除
1. slot 内容
<span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-button type="text" size="mini" @click="() => edit(node, data)">edit</el-button><el-button type="text" size="mini" @click="() => append(data)">Append</el-button><el-buttontype="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span>
</span>2. 设置函数
{// 2.1 编辑,子级可以弹窗回显名称,然后修改名称edit(node, data) {console.log(node, data);},// 2.2 新增,新增内容自己定,也可以弹窗自定义名称,通过接口返回 id 再拼接append(data) {const newChild = { id: this.id++, label: "testtest", children: [] };if (!data.children) {this.$set(data, "children", []);}data.children.push(newChild);},// 2.3 删除,可以先进行提示,提示确定后再删remove(node, data) {const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex((d) => d.id === data.id);children.splice(index, 1);}
}
三、整体代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><linkrel="stylesheet"href="https://unpkg.com/element-ui@2.15.14/lib/theme-chalk/index.css"/><style>.custom-tree-node {flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;}</style></head><body><script src="https://unpkg.com/vue@2.7.16/dist/vue.js"></script><script src="https://unpkg.com/element-ui@2.15.14/lib/index.js"></script><div id="app"><el-tree:check-strictly="true":data="data"@check-change="checkChange"ref="treeRef"show-checkboxdefault-expand-allnode-key="id"ref="tree"highlight-current:props="defaultProps"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-button type="text" size="mini" @click="() => edit(node, data)">edit</el-button><el-button type="text" size="mini" @click="() => append(data)">Append</el-button><el-buttontype="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree><div class="buttons"><el-button @click="getCheckedNodes">通过 node 获取</el-button><el-button @click="getCheckedKeys">通过 key 获取</el-button><el-button @click="setCheckedNodes">通过 node 设置</el-button><el-button @click="setCheckedKeys">通过 key 设置</el-button><el-button @click="resetChecked">清空</el-button></div></div><script>var Main = {methods: {edit(node, data) {console.log(node, data);},append(data) {const newChild = { id: this.id++, label: "testtest", children: [] };if (!data.children) {this.$set(data, "children", []);}data.children.push(newChild);},remove(node, data) {const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex((d) => d.id === data.id);children.splice(index, 1);},checkChange(data, checked, indeterminate) {this.node = data;this.checked = checked;this.indeterminate = indeterminate;// console.log("data, checked, indeterminate", data, checked, indeterminate);this.$nextTick(() => {console.log(data.id);const nodeInfo = this.$refs.treeRef.getNode(data.id);const { isLeaf, checked } = nodeInfo;this.nodeInfo = nodeInfo;console.log(nodeInfo);// console.log(// "nodeInfo, isLeaf, childNodes, checked",// nodeInfo,// isLeaf,// childNodes,// checked// );function getAllIds(arr, res = []) {for (let i = 0; i < arr.length; i++) {res.push(arr[i].id);if (arr[i].children && arr[i].children.length) {getAllIds(arr[i].children, res);}}return res;}console.log(this.$refs.treeRef.getCheckedKeys());if (!isLeaf) {const checkedIds = this.$refs.treeRef.getCheckedKeys();const ids = getAllIds(nodeInfo.data.children);console.log(ids);if (checked) {this.$refs.treeRef.setCheckedKeys(Array.from(new Set([...checkedIds, ...ids])));} else {this.$refs.treeRef.setCheckedKeys(Array.from(new Set(checkedIds.filter((item) => !ids.includes(item)))));}}});},getCheckedNodes() {console.log(this.$refs.tree.getCheckedNodes());},getCheckedKeys() {console.log(this.$refs.tree.getCheckedKeys());},setCheckedNodes() {this.$refs.tree.setCheckedNodes([{id: 5,label: "二级 2-1",},{id: 9,label: "三级 1-1-1",},]);},setCheckedKeys() {this.$refs.tree.setCheckedKeys([3]);},resetChecked() {this.$refs.tree.setCheckedKeys([]);},},data() {return {id: 10,data: [{id: 1,label: "一级 1",children: [{id: 4,label: "二级 1-1",children: [{id: 9,label: "三级 1-1-1",},{id: 10,label: "三级 1-1-2",},],},],},{id: 2,label: "一级 2",children: [{id: 5,label: "二级 2-1",},{id: 6,label: "二级 2-2",},],},{id: 3,label: "一级 3",children: [{id: 7,label: "二级 3-1",},{id: 8,label: "二级 3-2",},],},],defaultProps: {children: "children",label: "label",},};},};var Ctor = Vue.extend(Main);new Ctor().$mount("#app");</script></body>
</html>
四、codepen 在线编辑
https://codepen.io/CAILeiz/pen/MYgpYOW
相关文章:
Element@2.15.14-tree checkStrictly 状态实现父项联动子项,实现节点自定义编辑、新增、删除功能
背景:现在有一个新需求,需要借助树结构来实现词库的分类管理,树的节点是不同的分类,不同的分类可以有自己的词库,所以父子节点是互不影响的;同样为了选择的方便性,提出了新需求,选择…...
详细介绍如何使用rapidjson读取json文件
本文主要详细介绍如何使用rapidjson库来实现.json文件的读取,分为相关基础介绍、结合简单示例进行基础介绍、结合复杂示例进行详细的函数实现介绍等三部分。 一、相关基础 1、Json文件中的{} 和 [] 在 JSON 文件中,{} 和 [] 分别表示不同的数据结构&…...
【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget
目录 QLabel QFrame 例子: textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子: QTimer QProgressBar 例子: QCalendarWidget 例子: QLabel 标签控件,用来显示…...
设计模式-访问者设计模式
介绍 访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变个元素的类的前提下定义作用于这些元素的新操作。 问题:在一个机构里面有两种员工,1.Teacher 2.Engineer 员…...
Spring框架IOC
目录 一、Spring框架的介绍 1.1 Spring框架的概述 1.2 Spring框架的优点 二、Spring的核心 IOC技术 2.1 什么是IOC 2.2 IOC的程序入门 2.3 IOC技术总结 2.4 Spring框架的Bean管理的配置文件方式 一、Spring框架的介绍 1.1 Spring框架的概述 Spring是一个开放源代码的…...
有哪些免费的 ERP 软件可供选择?哪些 ERP 软件使用体验较好?
想找个 “免费” 的 ERP 软件? 咱得知道,ERP 那可是涉及财务、人力、供应链、采购、销售等好多方面的重要企业软件。功能这么全,能免费才怪呢!真要是有免费的,早就火遍大江南北,说不定把市场都垄断了&…...
思科CCNA认证都学什么考什么?
关注 工 仲 好:IT运维大本营CCNA考试要学的东西很多,你不要看它只是一个初级认证,但是它的专业内容知识是不少的,你想要学好也是需要下一番苦功的。 那么考CCNA需要学哪些东西呢?下面我们就来了解一下吧。 01、考CCN…...
模型部署学习笔记——模型部署关键知识点总结
模型部署学习笔记——模型部署关键知识点总结 模型部署学习笔记——模型部署关键知识点总结1. CUDA中Grid和Block的定义是什么?Shared Memory的定义?Bank Conflict的定义?Stream和Event的定义?2. TensorRT的工作流程?3…...
22智能 狄克斯特拉算法复习
狄克斯特拉算法 图 根据边有无方向分为: 有向图、无向图 根据边有无权重变量分为: 有权图、无权图 根据顶点是否连通分为: 连通图和非连通图入度:表示有多少条边指向该顶点出度:表示有多少条边从该顶点指出算法步骤&a…...
首个!艾灵参编的工业边缘计算国家标准正式发布
近日,艾灵参与编制的《面向工业应用的边缘计算 应用指南》(以下简称《标准》)国家标准正式发布,将于2025年5月1日起实施。这一里程碑式的成果,不仅标志着我国在工业边缘计算技术标准化领域取得了重大突破,成…...
curl也支持断点续传
curl断点续传 访问外网资源,特别是Github上比较大的资源,例如,笔者遇到的calico发布包,经常会遇到在浏览器上下载半途中断。 那么支持断点续传的下载工具,就是应对这种情况的好帮手! 简单的断点续传工具…...
交换机链路聚合(手动负载分担模式)(eNSP)
目录 交换机SW_C配置: 交换机-PC划分vlan: 交换机-交换机端口聚合: 交换机SW_D配置: 交换机-PC划分vlan: 交换机-交换机端口聚合: 验证: 链路聚合的端口清除: 交换机端口聚合的存在意义主要有以下几点: 增加带宽 提高冗余性和可靠性 实现负载均衡 降低成本 …...
jmeter 接口性能测试 学习笔记
目录 说明工具准备工具配置jmeter 界面汉化配置汉化步骤汉化结果图 案例1:测试接口接口准备线程组添加线程组配置线程组值线程数(Number of Threads)Ramp-Up 时间(Ramp-Up Period)循环次数(Loop Count&…...
`HashMap`、`Hashtable` 和 `HashSet`的区别
HashMap、Hashtable 和 HashSet 都是 Java 中常用的集合类,它们的功能和实现有所不同,尽管它们都使用哈希表(hash table)作为底层数据结构。以下是它们之间的主要区别: 1. HashMap 和 Hashtable 的区别 特性HashMapH…...
Arduino中解析JSON数据
JSON JSON(JavaScript Object Notation,即JavaScript对象表示法)是一种广泛采用的开放标准文件格式与数据交换格式。它兼具人类可读性和机器易解析性,使得数据的编写、阅读、生成及解析都变得十分便捷。JSON的设计不依赖于特定编…...
linux----文件访问(c语言)
linux文件访问相关函数 打开文件函数 - open 函数原型:int open(const char *pathname, int flags, mode_t mode);参数说明: pathname:这是要打开的文件的路径名,可以是绝对路径或者相对路径。例如,"/home/user/…...
源码分析之Openlayers中MousePosition鼠标位置控件
概述 本文主要介绍 Openlayers 中的MousePosition鼠标位置控件,该控件会创建一个元素在页面的右上方用来实时显示鼠标光标的位置坐标。该控件在实际应用很有效,可以实时获取鼠标位置,但是一般控件元素都会自定义。 源码分析 MousePosition…...
以ATTCK为例构建网络安全知识图
ATT&CK(Adversarial Tactics, Techniques, and Common Knowledge )是一个攻击行为知识库和模型,主要应用于评估攻防能力覆盖、APT情报分析、威胁狩猎及攻击模拟等领域。本文简单介绍ATT&CK相关的背景概念,并探讨通过ATT&a…...
myexcel的使用
参考: (1)api文档:https://www.bookstack.cn/read/MyExcel-2.x/624d8ce73162300b.md (2)源代码: https://github.com/liaochong/myexcel/issues 我: (1)m…...
Unity 上好用的插件
PlayerMaker BehaviorDesigner Cinemachine Timeline Hybrid Addressable AssetBundle Blower Simple Zoom 大地图上缩放和平移使用ScrollRect的好效果实现...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
