element-ui Tree 树形控件 过滤保留子级并获取过滤后的数据 多选改单选

本示例基于vue2 + element-ui

element-ui 的官网demo是只保留到过滤值一级的,并不会保留其子级

目标

1、Tree 树形控件 保留过滤值的子级

2、在第一次过滤数据的基础上进行第二次过滤

3、Tree 树形控件 多选改为单选,且只有最末端子级可以选择

不足之处

过滤时无法指定过滤哪一级的数据(保留其子级数据)

实际场景需求

  1. 第一次过滤时只过滤第三级数据
  2. 第二次过滤时在第一次过滤的基础上过滤最后一级

1 暂时无法实现(如果有大佬用前端方法实现,记得call我!)

2 过滤最后一级可以实现(代码随后附上)

先看效果

1、2

3  多选改单选效果

Tree 树形控件 保留过滤值的子级

<el-treeclass="filter-tree"node-key="id":data="treeData":props="defaultProps"default-expand-allshow-checkbox@check-change="handleCheckChange":filter-node-method="filterNode"ref="tree">
</el-tree>// 对树节点进行筛选时执行的方法
filterNode (value, data, node) {let parentNode = node.parent; // 父级nodelet labels = [node.label]; // 当前node的名字let level = 1; // 层级while (level < node.level) {labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字parentNode = parentNode.parent;level++;}return labels.some((d) => d.indexOf(value) !== -1);
},

在第一次过滤数据的基础上进行第二次过滤

1、下载插件库

npm install -S circular-json

2、在使用页面引入

import CircularJSON from 'circular-json'

3、代码应用

<template><div class="about-container"><h1>获取过滤后的tree数据</h1><el-inputclearableplaceholder="第一次过滤"@keyup.enter.native="handleFilter1"v-model="firstText"></el-input><el-inputstyle="margin-top: 10px;"clearableplaceholder="第二次过滤"@keyup.enter.native="handleFilter2"v-model="secondText"></el-input><el-button @click="handleFilter1(),handleFilter2()" type="primary" icon="el-icon-search">搜索</el-button><div><el-treeclass="filter-tree"node-key="id":data="treeData":props="defaultProps"default-expand-allshow-checkbox@check-change="handleCheckChange":filter-node-method="filterNode"ref="tree"></el-tree></div></div>
</template><script>// 在使用的组件内引入import CircularJSON from 'circular-json'export default {data() {return {// 第一次过滤firstText: '',// 第二次过滤secondText:'',// tree控件的渲染值treeData: [{id: 1,label: '一级1',children: [{id: 4,label: '二级1-1',children: [{id: 9,label: '三级1-1-1',children: [{id:91,label: '四级1'},{id:92,label: '四级2'}]}, {id: 10,label: '三级1-1-2'}]}]}, {id: 2,label: '一级2',children: [{id: 5,label: '二级2-1'}, {id: 6,label: '二级2-2'}]}, {id: 3,label: '一级',children: [{id: 7,label: '二级3-1'}, {id: 8,label: '二级3-2'},{id: 82,label: '四级3'}]},{id: 31,label: '奇迹',children: [{id: 71,label: '奇迹1'}, {id: 81,label: '奇迹2'}]}],defaultProps: {children: 'children',label: 'label'},// tree的原版备份数据deepCloneTreeData:[],// 第一次过滤后tree控件渲染数据firstFilterdata:[],}},mounted() {this.deepClone(this.treeData).then((res)=>{this.deepCloneTreeData = res;})},methods: {// 第一次过滤handleFilter1() {// 第一次过滤时没有输入值,即用tree控件的原始值if(!this.firstText){this.treeData = this.deepCloneTreeData;this.firstFilterdata = this.deepCloneTreeData;return}this.$refs.tree.filter(this.firstText)this.firstFilterdata = this.getFilterData();},// 第二次过滤handleFilter2() {// 基于第一次过滤出来的数据if(this.firstFilterdata.length > 0) this.treeData = this.firstFilterdata;this.$nextTick(()=>{this.$refs.tree.filter(this.secondText);})},// 对树节点进行筛选时执行的方法filterNode (value, data, node) {let parentNode = node.parent; // 父级nodelet labels = [node.label]; // 当前node的名字let level = 1; // 层级while (level < node.level) {labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字parentNode = parentNode.parent;level++;}return labels.some((d) => d.indexOf(value) !== -1);},// tree 的选择事件handleCheckChange(data, checked, indeterminate) {const arr = this.$refs.tree.getCheckedKeys()},// 需要获取过滤后的 Tree组件数据getFilterData() {const rootData = this.$refs.tree.root;if (rootData.visible) {const childNodesStr = CircularJSON.stringify(rootData.childNodes);const childNodes = CircularJSON.parse(childNodesStr);const filterData = this.recursionNodes(childNodes);return filterData;}},/*** 递归遍历数据* 这里解释一下为什么要用CircularJSON这个插件,因为element tree* node数据存在一个对象里的子项存在循环引用,存在循环引用的对象*/recursionNodes(childNodes) {const nodes = childNodes;const result = [];for (const item of nodes) {if (item.visible) {result.push(item.data);}if (item.childNodes && item.childNodes.length) {const tempResult = this.recursionNodes(item.childNodes);item.data.children = tempResult;}}return result;},/*** 深拷贝*/deepClone(obj){return new Promise((resolve) => {const { port1,port2 } = new MessageChannel();port1.postMessage(obj);port2.onmessage = (msg) => {resolve(msg.data)}})}},}
</script>

只过滤最后一级

/** * 数据处理* * 需要对每级数据进行level标记,方便后续过滤*/
treeData: [{id: 1,label: '一级1',level:1,children: [{id: 4,label: '二级1-1',level:2,children: [{id: 9,label: '三级1-1-1',level:3,children: [{id:91,label: '四级1',level:4,},{id:92,label: '四级2',level:4,}]}, {id: 10,label: '三级1-1-2',level:3,}]}]
}, {id: 2,label: '一级2',level:1,children: [{id: 5,label: '二级2-1',level:2,}, {id: 6,label: '二级2-2',level:2,}]
}, {id: 3,label: '一级',level:1,children: [{id: 7,label: '二级3-1',level:2,}, {id: 8,label: '二级3-2',level:2,},{id: 82,label: '四级3',level:2,}]
},{id: 31,label: '奇迹',level:1,children: [{id: 71,label: '奇迹1',level:2,}, {id: 81,label: '奇迹2',level:2,}]
}]// 对树节点进行筛选时执行的方法
filterNode(value, data, node) {/*** 筛选最后一级可用* * [4].includes(data.level* [] 中写入最后一级的level值*/if ([4].includes(data.level) && data.label.indexOf(value) !== -1) {console.log(value,data,node,'4-------',data.label.indexOf(value));let parentNode = node.parent; // 父级nodelet labels = [node.label]; // 当前node的名字let level = 1; // 层级while (level < node.level) {// console.log(labels,'labels');labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字parentNode = parentNode.parent;level++;}return labels.some((d) => d.indexOf(value) !== -1);}
},

Element tree组件 多选改为单选

<el-treeclass="treeRadio"check-strictly@check-change="deptCheck"deptCheck(data, check, childCheck) {if(check){this.$refs.tree.setCheckedNodes([data]);}
}// css 让父级不显示checkbox
::v-deep .el-tree .el-tree-node .is-leaf + .el-checkbox .el-checkbox__inner{display: inline-block;
}
::v-deep .el-tree .el-tree-node .el-checkbox .el-checkbox__inner{display: none;
}
::v-deep .treeRadio .el-checkbox__inner{border-radius: 50%;transform: scale(1.2);
}
// 样式改为单选框的样式
::v-deep .treeRadio .el-checkbox__inner{border-radius: 50%;transform: scale(1.2);
}

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

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

相关文章

Django 8 通用视图基础

1. 什么是通用视图 1. 在terminal 输入 django-admin startapp the_12回车 2. tutorial\settings.py 注册 INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.sta…

链接器--动态链接器--延迟绑定与动态链接器是什么?学习笔记二

内容在下面链接&#xff08;通过新建标签页打开&#xff09;&#xff1a; 链接器--动态链接器--延迟绑定与动态链接器是什么&#xff1f;学习笔记二一个例子来看延迟加载https://mp.weixin.qq.com/s?__bizMzkyNzYzMjMzNA&mid2247483713&idx1&snee90a5a7d59872287…

C++知识切片①:运算符重载之前置递增和后置递增

文章目录 前置递增的实现1.先写好main函数及头文件2.自定义MyInteger类3.重定义cout4.在类内实现前置递增 后置递增的实现完整代码 在进行运算符重载之前&#xff0c;不妨先看看常规的前置递增和后置递增的区别&#xff1a; 前置递增如a所示&#xff0c;a是先进行递增计算&…

人工智能大模型:定义、发展和应用

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

k8s中的容器探针

pod的容器健康检查---探针 probe&#xff1a;k8s对容器执行的定期检查&#xff0c;诊断。 探针的三种规则 所有的探针都是针对容器不是针对pod 1、 存活探针---livenessProbe&#xff1a;探测容器是否正常运行。如果发现探测失败&#xff0c;会杀掉容器。容器会根据重启策略…

B端产品经理学习-对用户进行需求挖掘

目录&#xff1a; 用户需求挖掘的方法 举例&#xff1a;汽车销售系统的用户访谈-前期准备 用户调研提纲 预约用户做访谈 用户访谈注意点 我们对于干系人做完调研之后需要对用户进行调研&#xff1b;在C端产品常见的用户调研方式外&#xff0c;对B端产品仍然适用的 用户需…

顺序表——习题

1. 轮转数组 代码实现&#xff1a; // 逆置数组 void nizhi_array(int *nums, int l, int r) { // 左闭右闭if (l > r) {return ;}for (int i l, j r; i < j; i, j--) {int temp nums[i];nums[i] nums[j];nums[j] temp;} }void rotate(int *nums, int numsSize, int…

C语言中关于strcpy函数的理解

strcpy的功能是将源指向的字符串复制到另外一个字符串中 目标指向的数组的大小应该要足够长&#xff0c;避免让源字符串中的数据溢出 关于这个函数的具体用法&#xff0c;我们可以看看下面这个程序 注意&#xff1a;strcpy函数的头文件是<string.h>&#xff0c;我们在用…

Arduino开发实例-EMG 肌肉信号传感器

EMG 肌肉信号传感器 文章目录 EMG 肌肉信号传感器1、EMG 肌肉信号传感器介绍2、硬件准备及接线3、代码实现1、EMG 肌肉信号传感器介绍 在医学研究中,测量肌肉的活动、收缩和扩张非常重要。 EMG 肌肉传感器测量肌肉活动并产生信号以显示扩张和收缩量。 因此,输出取决于所选肌…

JavaWeb——后端之maven

三、后端Web开发 1. Maven 1.1 概念 概念&#xff1a; 一款用于管理和构建java项目的工具&#xff0c;是apache下的一个开源项目 作用&#xff1a; 依赖管理&#xff1a;jar包&#xff0c;避免版本冲突问题——不用手动导jar包&#xff0c;只需要在配置文件&#xff08;pom…

【数据库原理】(8)关系数据库的关系代数

关系数据语言可以分为三类: 关系代数、关系演算和介于关系代数与关系演算之间的语言 SQL。 下面专门讲述用对关系进行运算来表达查询要求的关系代数。关系代数的运算对象是关系&#xff0c;运算结果也是关系。关系代数用到的运算符包括四类:集合运算符、专门的关系运算符、算术…

若依项目(ruoy-vue)多模块依赖情况简要分析

主pom文件关键点分析 properties标签声明变量信息&#xff1a;版本号、编码类型、java版本spring-boot依赖形式&#xff1a;spring-boot-dependencies、pom、importdependencies中添加本项目内部模块&#xff0c;同时在modules中声明模块packaging打包选择pom设置打包maven-co…

VMware Workstation虚拟机CentOS 7.9 配置固定ip的步骤

VMware Workstation虚拟机CentOS7.9配置固定ip的步骤 编辑虚拟机 打开VMware Workstation。 选择要配置的虚拟机&#xff0c;但不要启动它。 点击“编辑虚拟机设置”&#xff08;Edit virtual machine settings&#xff09;。 选择“网络适配器”&#xff08;Network Adapter&…

win11电脑图形卡不支持或已禁用硬件加速怎么解决,N卡GPU看不到cuda进程怎么办

摘要 亲&#xff0c;很高兴为你解答。win11电脑图形卡不支持或已禁用硬件加速解决方法&#xff1a;1、点击任务栏上的开始图标&#xff0c;在打开的菜单中&#xff0c;点击设置&#xff0c;&#xff08;快捷键WINX&#xff0c;点击设置&#xff09;。2、Windows系统 设置窗口&a…

找不到vcruntime140.dll怎么处理?6个修复教程分享

本文将详细介绍vcruntime140.dll文件的相关内容&#xff0c;并提供6个不同的修复教程&#xff0c;帮助大家解决这一问题。 一、vcruntime140.dll是什么文件&#xff1f; vcruntime140.dll是Visual C Redistributable Packages的一部分&#xff0c;它是Microsoft Visual Studi…

C# 2中的一些小特性

一、局部类型 在C#当中有这样一个关键字partial 用来声明类&#xff0c;结构&#xff0c;接口分为多个部分来声明。使用场景可以一部分类中写实例方法&#xff0c;一部分写属性&#xff0c;我在实际工作测试中就是将属性与实际方法是分开的。相互之间的成员互相通用。 举个例子…

秋招复习之数据结构

目录 前言 1 数据结构分类 2 基本数据类型 3 数字编码 4 字符编码 总结 前言 秋招复习之数据结构&#xff0c;数据结构分类、基本数据类型、字符编码、数字编码等基础知识。 1 数据结构分类 数据结构分为逻辑结构和物理结构。 逻辑结构分为线性数据结构&#xff08;数组链表…

卷麻了,00后测试用例写的比我还好,简直无地自容...........

经常看到无论是刚入职场的新人&#xff0c;还是工作了一段时间的老人&#xff0c;都会对编写测试用例感到困扰&#xff1f;例如&#xff1a; 如何编写测试用例&#xff1f; 作为一个测试新人&#xff0c;刚开始接触测试&#xff0c;对于怎么写测试用例很是头疼&#xff0c;无法…

私域和微商有什么区别?

私域和微商到底有什么区别呢&#xff1f;其实这两个东西有着本质性区别。 私域&#xff1a; 通过原有商业或者新媒体方式获取粉丝或顾客&#xff0c;然后用微信等社交工具&#xff0c;多方位展现&#xff0c;人格专业。 最终目标是让粉丝或顾客成为品牌或IP的朋友&#xff0…

Ajax基础入门_Ajax概述,同步与异步,Axios的使用,JSON数据及FastJSON的使用

Ajax 文章目录 Ajax1 概述2 作用3 同步和异步3.1 同步3.2 异步 4 代码编写4.1 服务端4.2 客户端 5 Axios5.1 使用5.2 代码5.2.1 前端5.2.2 后端 5.3 请求方法别名 6 JSON6.1 概述6.2 JSON 基础语法6.2.1 定义格式6.2.2 js 对象与JSON的转换 6.3 发送异步请求携带参数6.4 JSON串…