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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/64506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

概率论得学习和整理27:关于离散的数组 随机变量数组的均值,方差的求法3种公式,思考和细节。

目录 1 例子1&#xff1a;最典型的&#xff0c;最简单的数组的均值&#xff0c;方差的求法 2 例子1的问题&#xff1a;例子1只是1个特例&#xff0c;而不是普遍情况。 2.1 例子1各种默认假设&#xff0c;导致了求均值和方差的特殊性&#xff0c;特别简单。 2.2 我觉得 加权…

【HarmonyOS NEXT】Web 组件的基础用法以及 H5 侧与原生侧的双向数据通讯

关键词&#xff1a;鸿蒙、ArkTs、Web组件、通讯、数据 官方文档Web组件用法介绍&#xff1a;文档中心 Web 组件加载沙箱中页面可参考我的另一篇文章&#xff1a;【HarmonyOS NEXT】 如何将rawfile中文件复制到沙箱中_鸿蒙rawfile 复制到沙箱-CSDN博客 目录 如何在鸿蒙应用中加…

ASP.NET Core - 依赖注入 自动批量注入

依赖注入配置变形 随着业务的增长&#xff0c;我们项目工作中的类型、服务越来越多&#xff0c;而每一个服务的依赖注入关系都需要在入口文件通过Service.Add{}方法去进行注册&#xff0c;这将是非常麻烦的&#xff0c;入口文件需要频繁改动&#xff0c;而且代码组织管理也会变…

Spring Boot 3.X:Unable to connect to Redis错误记录

一.背景 最近在搭建一个新项目&#xff0c;本着有新用新的原则&#xff0c;项目选择到了jdk17SpringBoot3.4。但是在测试Redis连接的时候却遇到了以下问题&#xff1a; redis连不上了。于是我先去检查了配置文件的连接信息&#xff0c;发现没问题&#xff1b;再去检查配置类&am…

FFmpeg第一话:FFmpeg 简介与环境搭建

FFmpeg 探索之旅 一、FFmpeg 简介与环境搭建 二、FFmpeg 解码详解 第一话&#xff1a;FFmpeg 简介与环境搭建 FFmpeg 探索之旅一、前言二、FFmpeg 是什么&#xff1f;三、简单介绍其历史背景四、为什么用 C学习 FFmpeg&#xff1f;&#xff08;一&#xff09;高性能优势&#…

(vue)el-table在表头添加筛选功能

(vue)el-table在表头添加筛选功能 筛选前&#xff1a; 选择条件&#xff1a; 筛选后&#xff1a; 返回数据格式: 代码: <el-tableref"filterTable":data"projectData.list"height"540":header-cell-style"{border-bottom: 1px soli…

流程引擎Activiti性能优化方案

流程引擎Activiti性能优化方案 Activiti工作流引擎架构概述 Activiti工作流引擎架构大致分为6层。从上到下依次为工作流引擎层、部署层、业务接口层、命令拦截层、命令层和行为层。 基于关系型数据库层面优化 MySQL建表语句优化 Activiti在MySQL中创建默认字符集为utf8&…

Vue3源码笔记阅读1——Ref响应式原理

本专栏主要用于记录自己的阅读源码的过程,希望能够加深自己学习印象,也欢迎读者可以帮忙完善。接下来每一篇都会从定义、运用两个层面来进行解析 定义 运用 例子:模板中访问ref(1) <template><div>{{str}}</div> </template> <script> impo…

神经网络基础-神经网络搭建和参数计算

文章目录 1.构建神经网络2. 神经网络的优缺点 1.构建神经网络 在 pytorch 中定义深度神经网络其实就是层堆叠的过程&#xff0c;继承自nn.Module&#xff0c;实现两个方法&#xff1a; __init__方法中定义网络中的层结构&#xff0c;主要是全连接层&#xff0c;并进行初始化。…

Dcoker Redis哨兵模式集群介绍与搭建 故障转移 分布式 Java客户端连接

介绍 Redis 哨兵模式&#xff08;Sentinel&#xff09;是 Redis 集群的高可用解决方案&#xff0c;它主要用于监控 Redis 主从复制架构中的主节点和从节点的状态&#xff0c;并提供故障转移和通知功能。通过 Redis 哨兵模式&#xff0c;可以保证 Redis 服务的高可用性和自动故…

机器学习之交叉熵

交叉熵&#xff08;Cross-Entropy&#xff09;是机器学习中用于衡量预测分布与真实分布之间差异的一种损失函数&#xff0c;特别是在分类任务中非常常见。它源于信息论&#xff0c;反映了两个概率分布之间的距离。 交叉熵的数学定义 对于分类任务&#xff0c;假设我们有&#…

Scala的泛型界限

泛型界限 上限 泛型的上限&#xff0c;下限。对类型的更加具体的约束&#xff01; 如果给某个泛型设置了上界&#xff1a;这里的类型必须是上界 如果给某个泛型设置了下界&#xff1a;这里的类型必须是下界

vscode中同时运行两个python文件(不用安装插件)

如何在vscode中同时运行两个python文件呢&#xff1f;今天在工作中遇到了这个问题。 查了网上的方法是安装coder runner插件&#xff0c;后来发现自身就有这个功能。所以记录一下,方便后续查找: 这是我的第一个文件&#xff0c;点击右上角的运行旁边的小箭头&#xff0c;有一…

python rabbitmq实现简单/持久/广播/组播/topic/rpc消息异步发送可配置Django

windows首先安装rabbitmq 点击参考安装 1、环境介绍 Python 3.10.16 其他通过pip安装的版本(Django、pika、celery这几个必须要有最好版本一致) amqp 5.3.1 asgiref 3.8.1 async-timeout 5.0.1 billiard 4.2.1 celery 5.4.0 …

Numpy基本介绍

目录 1、Numpy的优势 1.1、ndarray介绍 1.2、ndarray与Python原生list运算效率对比 1.3、ndarray的优势 1.3.1、内存块风格 1.3.2、ndarray支持并行化运算(向量化运算) 1.3.3、效率远高于纯Python代码 2、N维数组-ndarray 2.1、ndarray的属性 2.2、ndarray的形状 2…

XXE练习

pikachu-XXE靶场 1.POC:攻击测试 <?xml version"1.0"?> <!DOCTYPE foo [ <!ENTITY xxe "a">]> <foo>&xxe;</foo> 2.EXP:查看文件 <?xml version"1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SY…

正则表达式在线校验(RegExp) - 加菲工具

正则表达式在线校验 - 加菲工具 打开网站 加菲工具 选择“正则表达式在线校验” 或者直接打开https://www.orcc.online/tools/regexp 输入待校验的源文本与正则表达式&#xff0c;点击“校验”按钮 需要注意检验后的内容可能存在多空格&#xff0c;可以拉下去看看~

java后端环境配置

因为现在升学了&#xff0c;以前本来想毕业干java的&#xff0c;很多java的环境配置早就忘掉了&#xff08;比如mysql maven jdk idea&#xff09;&#xff0c;想写个博客记录下来&#xff0c;以后方便自己快速搭建环境 JAVA后端开发配置 环境配置jdkideamavenMySQLnavicate17…

51c嵌入式~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/12847563 一、UCIe 2.0 日前&#xff0c;通用芯粒互连&#xff08;UCIe&#xff09;产业联盟最新公布了 UCIe 2.0 规范&#xff0c;支持可管理性标准化系统架构&#xff0c;并全面解决了系统级封装&#xff08;SiP&#x…

解决电脑网速慢问题:硬件检查与软件设置指南

电脑网速慢是许多用户在使用过程中常见的问题&#xff0c;它不仅会降低工作效率&#xff0c;还可能影响娱乐体验。导致电脑网速慢的原因多种多样&#xff0c;包括硬件问题、软件设置和网络环境等。本文将从不同角度分析这些原因&#xff0c;并提供提高电脑网速的方法。 一、检查…