当前位置: 首页 > news >正文

el-select 和el-tree二次封装

前言

本文章是本人在开发过程中,遇到使用树形数据,动态单选或多选的需求,element中没有这种组件,故自己封装一个,欢迎多多指教

开发环境:element-UI、vue2

组件效果

单选

多选

组件引用

<treeselect v-model="form.parentId":options="deptOptions":props="{value:'id',label:'name',children: 'children'}":placeholder="'选择上级部门'"/>

组件代码

<template><div><el-selectref="treeSelect"popper-class="custom-select-popper"style="width: 100%"v-model="valueLabel":clearable="clearable":placeholder="placeholder":multiple="multiple"@clear="handleClear"@remove-tag="handleRemoveTag"><el-input v-if="filter"v-model="filterText":placeholder="filterPlaceholder" style="margin-top: -6px;"/><el-option :value="value" :label="option.name" class="select-options"><el-treeid="tree-option"ref="treeSelectTree":accordion="accordion":data="options":props="props":node-key="props.value":highlight-current="!multiple":show-checkbox="multiple":check-strictly="checkStrictly":default-expand-all="expandAll":expand-on-click-node="multiple":filter-node-method="filterNode"@node-click="handleNodeClick"@check="handleNodeCheckbox"><span slot-scope="{ node, data }" class="tree_label">{{ node.label }}</span></el-tree></el-option></el-select></div>
</template>
<script>
export default {name: 'TreeSelect',model: {prop: 'value',event: 'change'},props: {value: {type: [String, Number, Object, Array],default: () => {return ''}},clearable: {type: Boolean,default: true},placeholder: {type: String,default: '请选择'},multipleLimit: {type: Number,default: 2},//--------- filter props -----filter: {type: Boolean,default: true},filterPlaceholder: {type: String,default: '请输入关键字'},//----- tree props -----accordion: {type: Boolean,default: false},options: {type: Array,default: () => {return []}},props: {type: Object,default: () => {return {value: 'id',label: 'label',children: 'children'}}},expandAll: {type: Boolean,default: false},checkStrictly: {type: Boolean,default: false}},data() {return {tp: {value: 'id',label: 'label',children: 'children',prentId: 'parentId'},multiple: false,valueLabel: [],option: {id: '',name: ''},filterText: undefined,valueId: [],treeIds: []}},watch: {valueId() {if (this.multiple) {let valueStr = ''if (this.value instanceof Array) {valueStr = this.value.join()} else {valueStr = '' + this.value}if (valueStr !== this.valueId.join()) {this.$emit('change', this.valueId)}} else {let id = this.valueId.length > 0 ? this.valueId[0] : undefinedif (id !== this.value) {this.$emit('change', id)}}},value: {handler(newVal, oldVal) {if (newVal !== oldVal) {this.init()}}},filterText: {handler(newVal, oldVal) {if (newVal !== oldVal) {this.$refs.treeSelectTree.filter(newVal)}}}},mounted() {for (let key in this.tp) {if (this.props[key] !== undefined) {this.tp[key] = this.props[key]}}this.multiple = this.multipleLimit > 1this.init()this.$nextTick(() => {if (this.multiple) {document.getElementsByClassName('el-select__tags')[0].style.maxHeight = document.getElementsByClassName('el-select')[0].offsetHeight * 2 - 4 + 'px'}})},methods: {init() {if (this.value instanceof Array) {this.valueId = this.value} else if (this.value === undefined) {this.valueId = []} else {this.valueId = [this.value]}if (this.multiple) {for (let id of this.valueId) {this.$refs.treeSelectTree.setChecked(id, true, false)}} else {this.$refs.treeSelectTree.setCurrentKey(this.valueId.length > 0 ? this.valueId[0] : undefined)}this.initValueLabel()this.initTreeIds()this.initScroll()},// 初始化滚动条initScroll() {this.$nextTick(() => {let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')scrollBar.forEach((ele) => (ele.style.width = 0))})},initTreeIds() {let treeIds = []let _this = thisfunction traverse(nodes) {for (let node of nodes) {treeIds.push(node[_this.tp.value])if (node[_this.tp.children]) {traverse(node[_this.tp.children])}}}traverse(this.options)this.treeIds = treeIds},initValueLabel() {let labels = []let _this = thisfor (let id of this.valueId) {let node = this.traverse(this.options, node => node[_this.tp.value] === id)if (node) {labels.push(node[_this.tp.label])}}if (this.multiple) {this.valueLabel = labelsthis.option.name = labels.join()} else {this.valueLabel = labels.length > 0 ? labels[0] : undefinedthis.option.name = this.valueLabel}},traverse(tree, func) {for (let node of tree) {if (func(node)) {return node}if (node[this.tp.children]) {let result = this.traverse(node[this.tp.children], func)if (result !== undefined) {return result}}}return undefined},handleClear() {this.valueLabel = []this.valueId = []if (this.multiple) {for (let id of this.treeIds) {this.$refs.treeSelectTree.setChecked(id, false, false)}} else {this.$refs.treeSelectTree.setCurrentKey(null)}},/* 树filter方法 */filterNode(value, data) {if (!value) return truereturn data[this.props.label].indexOf(value) !== -1},/* 树节点点击事件 */handleNodeClick(data, node) {if (!this.multiple) {this.filterText = ''this.valueId = [data[this.tp.value]]}if(node.childNodes){node.expanded = true}},handleNodeCheckbox(data, node) {if (this.multiple) {if (this.multipleLimit >= node.checkedKeys.length) {this.valueId = node.checkedKeys} else {this.$refs.treeSelectTree.setChecked(data, false, !this.checkStrictly)this.$message.error('最多选择' + this.multipleLimit + '项')}}},handleRemoveTag(tag) {let n = this.traverse(this.options, node => node[this.tp.label] === tag)if (n) {this.$refs.treeSelectTree.setChecked(n[this.tp.value], false, !this.checkStrictly)}this.valueId = this.$refs.treeSelectTree.getCheckedKeys()}}
}</script><style scoped lang="scss">
::v-deep .el-select__tags {overflow: auto;
}
.custom-select-popper{}.el-scrollbar {.el-scrollbar__view {.el-select-dropdown__item {height: auto;max-height: 300px;padding: 0;overflow: hidden;overflow-y: auto;}.el-select-dropdown__item.selected {font-weight: normal;}}
}ul li {.el-tree {.el-tree-node__content {height: auto;padding: 0 20px;}.el-tree-node__label {font-weight: normal;}.is-current > .el-tree-node__label{color: #409eff;font-weight: 700;}}
}.tree_label {line-height: 23px;.label_index {background-color: rgb(0, 175, 255);width: 22px;height: 22px;display: inline-flex;border-radius: 4px;.label_index_font {color: #ffffff;width: 100%;text-align: center;}}
}
</style>

相关文章:

el-select 和el-tree二次封装

前言 本文章是本人在开发过程中&#xff0c;遇到使用树形数据&#xff0c;动态单选或多选的需求&#xff0c;element中没有这种组件&#xff0c;故自己封装一个&#xff0c;欢迎多多指教 开发环境&#xff1a;element-UI、vue2 组件效果 单选 多选 组件引用 <treeselec…...

C++11:多线程编程

目录 线程库基本用法创建线程给线程传递参数线程分离 常见数据未定义错误传递指针或引用指向局部变量的问题传递指针或引用指向已释放的内存的问题类成员函数作为入口函数&#xff0c;类对象被提前释放智能指针来解决该问题入口函数为类的私有成员函数 互斥量死锁 lock_guard与…...

【H2O2|全栈】JS进阶知识(八)ES6(4)

目录 前言 开篇语 准备工作 浅拷贝和深拷贝 浅拷贝 概念 常见方法 弊端 案例 深拷贝 概念 常见方法 弊端 逐层拷贝 原型 构造函数 概念 形式 成员 弊端 显式原型和隐式原型 概念 形式 constructor 概念 形式 原型链 概念 形式 结束语 前言 开篇语…...

OmniDiskSweeper :一款专为 macOS 设计的磁盘使用分析工具

OmniDiskSweeper 是一款专为 macOS 设计的磁盘使用分析工具&#xff0c;由 The Omni Group 开发。它的主要目的是帮助用户可视化磁盘上的文件和文件夹&#xff0c;并找出占用大量空间的文件&#xff0c;从而帮助用户释放磁盘空间。 OmniDiskSweeper 的特点包括&#xff1a; 简…...

【什么是Redis?】

Redis&#xff1a;高性能内存数据库的深度探索 在当今这个数据驱动的世界里&#xff0c;数据库的选择直接关系到应用程序的性能、可扩展性和可靠性。在众多数据库解决方案中&#xff0c;Redis以其卓越的性能、丰富的数据结构和灵活的使用场景脱颖而出&#xff0c;成为众多开发…...

React第十六章(useLayoutEffect)

useLayoutEffect useLayoutEffect 是 React 中的一个 Hook&#xff0c;用于在浏览器重新绘制屏幕之前触发。与 useEffect 类似。 用法 useLayoutEffect(() > {// 副作用代码return () > {// 清理代码}}, [dependencies]);参数 setup&#xff1a;Effect处理函数,可以返回…...

shell 基础知识2 ---条件测试

目录 一、条件测试的基本语法 二、文件测试表达式 三、字符串测试表达式 四、整数测试表达式 五、逻辑操作符 六、实验 为了能够正确处理 Shell 程序运行过程中遇到的各种情况&#xff0c; Linux Shell 提供了一组测试运算符。 通过这些运算符&#xff0c;Shell 程序能够…...

【线程】Java线程操作

【线程】Java线程操作 一、启动线程1.1 run()和start()的区别 二、终止线程三、等待线程四、线程的状态 一、启动线程 Java中通过start()方法来启动一个线程&#xff0c;其次我们要着重理解start()和run()的区别。 1.1 run()和start()的区别 我们通过一份代码来进行观察&…...

Linux内核

Linux内核是Linux操作系统的核心部分&#xff0c;它管理着硬件资源并提供基本的服务给用户程序。以下是Linux内核的几个关键方面&#xff1a; 1. 架构&#xff1a; 单内核设计&#xff1a;Linux采用的是单内核设计&#xff0c;这意味着所有操作系统服务都在一个地址空间内运行…...

Sentinel服务保护

Sentinel是阿里巴巴开源的一款服务保护框架&#xff0c;目前已经加入SpringCloudAlibaba中。官方网站&#xff1a; home | Sentinel Sentinel 的使用可以分为两个部分: 核心库&#xff08;Jar包&#xff09;&#xff1a;不依赖任何框架/库&#xff0c;能够运行于 Java 8 及以…...

python代码制作数据集的测试和数据质量检测思路

前言 本文指的数据集为通用数据集&#xff0c;并不单是给机器学习领域使用。包含科研和工业领域需要自己制作数据集的。 首先&#xff0c;在制作大型数据集时&#xff0c;代码错误和数据问题可能会非常复杂。 前期逻辑总是简单的&#xff0c;库库一顿写&#xff0c;等排查的时…...

笔记记录 k8s-install

master节点安装: yum upgrade -y 更新系统 yum update -y 升级内核 ifconfig ens33 关闭swap swapoff -a (临时) vim /etc/fstab (永久) #/dev/mapper/cl-swap swap swap defaults 0 0 vim /etc/sysctl.conf vm.swappin…...

丹摩征文活动|基于丹摩算力的可图(Kolors)的部署与使用

Kolors是一个以生成图像为目标的人工智能系统&#xff0c;可能采用了类似于OpenAI的DALLE、MidJourney等文本生成图像的技术。通过自然语言处理&#xff08;NLP&#xff09;和计算机视觉&#xff08;CV&#xff09;相结合&#xff0c;Kolors能够根据用户提供的文本描述生成符合…...

【Vue】 npm install amap-js-api-loader指南

前言 项目中的地图模块突然打不开了 正文 版本太低了&#xff0c;而且Vue项目就应该正经走项目流程啊喂&#xff01; npm i amap/amap-jsapi-loader --save 官方说这样执行完&#xff0c;就这结束啦&#xff01;它结束了&#xff0c;我还没有&#xff0c;不然不可能记录这篇文…...

MacOS下的Opencv3.4.16的编译

前言 MacOS下编译opencv还是有点麻烦的。 1、Opencv3.4.16的下载 注意&#xff0c;我们使用的是Mac&#xff0c;所以ios pack并不能使用。 如何嫌官网上下载比较慢的话&#xff0c;可以考虑在csdn网站上下载&#xff0c;应该也是可以找到的。 2、cmake的下载 官网的链接&…...

Android中的依赖注入(DI)框架Hilt

Hilt 是 Android 提供的一种依赖注入&#xff08;DI&#xff09;框架&#xff0c;它基于 Dagger&#xff0c;目的是简化依赖注入的使用&#xff0c;提供更易用的接口和与 Android 生命周期组件的紧密集成。下面是 Hilt 的详细介绍。 为什么选择 Hilt? 依赖注入的优势&#xf…...

5.STM32之通信接口《精讲》之USART通信---实验串口接收程序

根据上节&#xff0c;我们一已经完成了串口发送程序的代码&#xff0c;并且深入的解析探索了串口的原理&#xff0c;接下来&#xff0c;Whappy小编将带领大家进入串口接收程序的探索与实验&#xff0c;并将结合上一节串口发送一起来完成串口的发送和接收实验。 上来两张图 上图…...

【Redis_Day6】Hash类型

【Redis_Day6】Hash类型 Hash类型操作hash的命令hset&#xff1a;设置hash中指定的字段&#xff08;field&#xff09;的值&#xff08;value&#xff09;hsetnx&#xff1a;想hash中添加字段并设置值hget&#xff1a;获取hash中指定字段的值hexists&#xff1a;判断hash中是否…...

[开源] SafeLine 好用的Web 应用防火墙(WAF)

SafeLine&#xff0c;中文名 “雷池”&#xff0c;是一款简单好用, 效果突出的 Web 应用防火墙(WAF)&#xff0c;可以保护 Web 服务不受黑客攻击 一、简介 雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 SQL 注入、XSS、 代码注…...

40分钟学 Go 语言高并发:Select多路复用

Select多路复用 学习目标 知识点掌握程度应用场景select实现原理深入理解底层机制channel通信和多路选择超时处理掌握超时控制方法避免阻塞和资源浪费优先级控制理解优先级实现处理多个channel的顺序性能考虑了解性能优化点高并发场景优化 1. Select实现原理 让我们通过一个…...

SenseVoice-Small ONNX开源方案:支持私有化部署的国产语音识别新标杆

SenseVoice-Small ONNX开源方案&#xff1a;支持私有化部署的国产语音识别新标杆 1. 项目简介 SenseVoice-Small ONNX是一个专为普通硬件设计的轻量化语音识别工具。基于FunASR开源框架的SenseVoiceSmall模型&#xff0c;通过Int8量化技术大幅降低资源消耗&#xff0c;让语音…...

NVMe 2.0 Boot Partitions:解锁高效固件更新的双分区机制

1. 为什么我们需要NVMe 2.0的双启动分区&#xff1f; 想象一下你正在给手机升级系统&#xff0c;突然断电了——传统单分区方案会让设备直接变砖&#xff0c;而NVMe 2.0的双启动分区就像给系统上了双保险。这个设计最初是为了解决企业级SSD在724小时运行时的固件更新难题&#…...

大厂笔试面试八股文-算法-数组常考题-final

刷了200道数组题,笔试面试还是不会做?这10道搞懂就够了 刷了200道数组题,面试还是不会做? 问题不是你刷得不够多,而是没抓住核心套路。 我整理了35道大厂真题,发现其实就5个核心技巧。今天把最重要的10道题和背后的套路,全部分享给你。 offer直通车-大厂校招大礼包&#x…...

4步完成Axure本地化设置:让新手轻松上手的中文界面方案

4步完成Axure本地化设置&#xff1a;让新手轻松上手的中文界面方案 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包&#xff0c;不定期更新。支持 Axure 9、Axure 10。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn …...

TMSpeech:开源本地语音转文字工具的隐私革命

TMSpeech&#xff1a;开源本地语音转文字工具的隐私革命 【免费下载链接】TMSpeech 腾讯会议摸鱼工具 项目地址: https://gitcode.com/gh_mirrors/tm/TMSpeech 在数字化办公浪潮中&#xff0c;语音转文字工具已成为效率提升的关键助手&#xff0c;但云端处理的隐私泄露风…...

导出浏览器网络日志 har 后缀的日志是什么 怎么打开

导出浏览器网络日志 har 后缀的日志是什么 怎么打开 一、实机演示二、har 后缀的日志是什么 .har 后缀的日志文件是一种专门用于记录和分析网页网络活动的文件格式。 &#x1f4c4; HAR 文件是什么&#xff1f; HAR 的全称是 HTTP ARchive。它本质上是一个标准的 JSON 文件&…...

5步精通Trilium中文版:构建高效个人知识管理系统

5步精通Trilium中文版&#xff1a;构建高效个人知识管理系统 【免费下载链接】trilium-translation Translation for Trilium Notes. Trilium Notes 中文适配, 体验优化 项目地址: https://gitcode.com/gh_mirrors/tr/trilium-translation 认识Trilium&#xff1a;重新定…...

springboot+vue基于web的社区交互图书管理系统的设计系统

目录同行可拿货,招校园代理 ,本人源头供货商系统功能模块划分关键技术实现数据库设计要点社区交互设计安全防护措施项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作同行可拿货,招校园代理 ,本人源头供货商 系统功能模块划分 后…...

ai辅助开发,让快马智能生成centos下openclaw安装与配置的疑难解决方案

在CentOS系统上安装和配置OpenClaw这类工具时&#xff0c;经常会遇到各种依赖冲突、环境配置问题&#xff0c;以及需要定制化爬取规则的情况。传统方式下&#xff0c;我们需要手动查阅文档、调试命令&#xff0c;甚至反复尝试不同版本的依赖包&#xff0c;过程相当耗时。而借助…...

React-Grid-Layout外部拖拽:从零构建可视化编辑体验

React-Grid-Layout外部拖拽&#xff1a;从零构建可视化编辑体验 【免费下载链接】react-grid-layout A draggable and resizable grid layout with responsive breakpoints, for React. 项目地址: https://gitcode.com/gh_mirrors/re/react-grid-layout 在构建现代Web应…...