ElementUI实现在下拉列表里面进行搜索

news2024/11/25 16:22:57

分析:

在这里插入图片描述

  1. 首先我们需要实现上图的效果,然后Element-UI的el-select是没有的,所以需要自己写
  2. 我们需要用到el-popover组件,然后使用它的v-model="visible"来实现控制显示
  3. 我们在el-popoverslot="reference" 放一个el-select
    • 使用popper-append-to-body="false"不需要插入浮动元素
    • 使用popper-class="hide-popper"定义浮窗class为hide-popper,并设置
      display:none,这样选中了就不会存在el-select的下拉选项
    • el-option 循环下面选择的list里面的元素,这样就可以在el-select展示选中的并存在删除
    • el-select双向绑定的就是自定义选择的数组
  • html:
    <template>
    	<div class="arrbox">
    		<!-- 通过visible控制显示还是隐藏 -->
    		<el-popover
    		v-model="visible"
    		placement="bottom-start"
    		width="auto"
    		>
    		<div slot="reference" class="check-select">
    			<!-- popper-append-to-body:不需要插入浮动元素,popper-class:设置类名并隐藏 -->
    			<el-select
    			ref="select"
    			v-model="currentval"
    			:style="{width:`${width}px`,height:`${height}`}"
    			multiple
    			:placeholder="placeholder"
    			:popper-append-to-body="false"
    			popper-class="hide-popper"
    			style="width:100%"
    			@visible-change="visibleChange"
    			@focus="getFocus"
    			> <el-option
    			v-for="item in selectItem"
    			:key="`${item.value}_k`"
    			:label="item.label"
    			:value="item.value"
    			/></el-select>
    		</div>
    		<!-- selectBxClick让select强制选中 -->
    		<div class="selectMain" :style="{'min-width':`${width-20}px`}" @click="selectBxClick">
    			<div class="seachButton">
    			<el-select
    				v-model="seachValue"
    				placeholder=" 请选择筛选"
    				style="width:70%;margin-right:10px;max-width:195px"
    				@visible-change="selectBxClick()"
    			>
    				<el-option
    				v-for="item in seachList"
    				:key="item.value"
    				:value="item.value"
    				:label="item.label"
    				/>
    			</el-select>
    			<div class="btn" @click="seachBtn">搜索</div>
    			</div>
    			 <div class="selectDiv">
                                  <div v-for="item in list.filter(n=>n.value=='all')" :key="item.value" class="list" :class="[currentval.indexOf(item.value)!=-1?'selected':'',item.value=='all'?'allCheck':'']" @click="clickItem(item)">{{ item.label }}</div>
    
                                  <div class="selectDivAuto">
                                    <div v-for="item in list.filter(n=>n.value!='all')" :key="item.value" class="list" :class="[currentval.indexOf(item.value)!=-1?'selected':'',item.value=='all'?'allCheck':'']" @click="clickItem(item)">{{ item.label }}</div>
                                  </div>
    
                                </div>
    		</div>
    		</el-popover>
    	</div>
    	</template>
    
  • js:
  1. 使用getFocus获取是否聚焦,聚焦了让visible=true,这样就可以显示出自定义的下拉选择项

  2. 通过visibleChange实施监听el-select,控制el-popover显示

  3. 在点击自定义的下拉选择项时,通过@click="selectBxClick"el-select一直聚焦,这样箭头就会一直向上

  4. 通过 @click="seachBtn"getList获取列表,具体需要自己去自定义

    // 模拟获取的数据
    	const seachClickList = [{value: '1',label: '测试1',type: '1'},{value: '2',label: '测试2',type: '1'},{value: '3',label: '测试3',type: '1'},{value: '4',label: '测试4',type: '2'},{value: '5',label: '测试5',type: '2'},{value: '6',label: '测试6',type: '2'},{value: '7',label: '测试7',type: '2'}]
    	export default {
    	model: {
    		prop: 'parentArr',
    		event: 'change-parentArr'
    	},
    	props: {
    		parentArr: {
    		type: Array,
    		default() {
    			return []
    		}
    		},
    		// 传入选中的item,主要时防止list里面没有选中的数据
    		parentSelectItem: {
    		type: Array,
    		default() {
    			return []
    		}
    		},
    		width: {
    		type: Number,
    		default: 300
    		},
    		height: {
    		type: Number,
    		default: 30
    		},
    		placeholder: {
    		type: String,
    		default: '请输入'
    		}
    	},
    	data() {
    		return {
    		seachList: [
    			{
    			value: '1',
    			label: '条件一'
    			},
    			{
    			value: '2',
    			label: '条件二'
    			}
    		],
    		visible: false,
    		currentval: [],
    		list: [],
    		selectItem: [],
    		seachValue: '1'
    		}
    	},
    	watch: {
    		seachValue: {
    		handler(value) {
    			this.getList(value)
    		},
    		deep: true,
    		immediate: true
    		},
    		parentArr: {
    		handler(value) {
    			this.currentval = value
    		},
    		deep: true,
    		immediate: true
    		},
    		parentSelectItem: {
    		handler(value) {
    			this.selectItem =  value.map(n => {
                                  if (n.value == 'all') {
                                    n.label = '全部'
                                  }
                                  return n
                                })
    		},
    		deep: true,
    		immediate: true
    		},
    		currentval: {
                            handler(value) {
                                    this.$emit('change-parentArr', value)
                            }
    		}
    	},
    	created() {
    	},
    	methods: {
    		getList(value) {
                            this.list = [{
                                    label: '全部',
                                    value: 'all'
                            }, ...seachClickList.filter(n => n.type == value)]
                            this.getSelectItem()
    		},
    		// 获取选中的item
    		getSelectItem() {
                            const noItemList = this.currentval.map(n => {
                                    if (this.selectItem.findIndex(i => i.value == n) == -1) {
                                    return n
                                    }
                                    return null
                            }).filter(n => n != null)
                            noItemList.forEach(item => {
                                    const index = this.list.findIndex(i => i.value == item)
                                    if (index != -1) {
                                    this.selectItem.push(this.list[index])
                                    }
                            })
    		},
    		getFocus() {
                            this.visible = true
    		},
    		visibleChange(data) {
                            this.visible = data
    		},
    		selectBxClick() {
                            // 避免点击框体时组件消失
                            this.$refs.select.visible = true
    		},
    		// 选择
    		clickItem(item) {
                          const index = this.currentval.indexOf(item.value)
                          if (index == -1) {
                            if (item.value == 'all') {
                              this.currentval = ['all']
                              this.selectItem = [{
                                label: '全部',
                                value: 'all'
                              }]
                            } else {
                              this.currentval.push(item.value)
                              this.selectItem.push(item)
                              const currentvalIndex = this.currentval.indexOf('all')
                              const selectItemIndex = this.selectItem.findIndex(n => n.value == 'all')
                              if (currentvalIndex != -1 && selectItemIndex != -1) {
                                this.selectItem.splice(selectItemIndex, 1)
                                this.currentval.splice(currentvalIndex, 1)
                              }
                            }
                          } else {
                            const itemIndex = this.selectItem.findIndex(n => n.value == item.value)
                            this.selectItem.splice(itemIndex, 1)
                            this.currentval.splice(index, 1)
                          }
                        },
    		// 搜索
    		seachBtn() {
                            this.getList()
    		}
    	}
    	}
    
  • css:

    1. selected属性使用了el-select的样式,让样子尽量一致
    .arrbox {
    display: inline-block;
    }
    .check-select{
    ::v-deep.hide-popper{
    	display: none;
    }
    }
    ::v-deep .el-input__suffix{
    i:not(.el-select__caret){
    	display: none;
    }
    }
    .selectMain {
    width: 100%;
    height: 100%;
    .seachButton{
    	width: 100%;
    	align-items: center;
    	display: flex;
    	div.btn{
    	width: 25%;
    	max-width: 70px;
    	max-width: 80px;
    	height: 40px;
    	display: flex;
    	align-items: center;
    	justify-content: center;
    	font-size: 12px;
    	color: #fff;
    	background-color: #409EFF;
    	border-radius: 5px;
    	cursor: pointer;
    	}
    }
    .selectDiv{
            width: 100%;
            max-width: 500px;
            margin-top: 10px;
            padding:  0 10px 0 0;
            .list{
              width: 100%;
              padding: 10px 20px 10px 10px;
              color: #666;
              cursor: pointer;
              position: relative;
              &.selected{
                color: #409EFF;
                &::after{
                  position: absolute;
                  right: 0px;
                  top: 50%;
                  transform: translateY(-50%);
                  font-family: element-icons;
                  content: "\e6da";
                  font-size: 12px;
                  font-weight: 700;
                  -webkit-font-smoothing: antialiased;
                }
              }
            }
            .selectDivAuto{
              width: calc(100% + 15px);
              max-height: 300px;
              overflow-y: auto;
              .list{
                padding: 10px 30px 10px 10px;
                &.selected::after{
                  right: 10px;
                }
              }
            }
    
          }
    }
    .allCheck{
    border-bottom: 1px solid rgb(228, 225, 225);
    }
    
  • 使用

    <template>
    	<seachSelectInput v-model="from.tag" :parentSelectItem='selectItem' :width="302" placeholder="请选择标签" />
    </template>
    <script>
    import seachSelectInput from ./seachSelectInput'
    export default {
    components: {
    	seachSelectInput
    },
    data(){
    	return{
    		from:{
    			tag:['1']
    		},
    		selectItem:[
    			{
    			value: '1',
    			label: '测试1'
    			}
    		]
    	}
    }
    }
    

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

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

相关文章

C++ 之 移动构造函数

1、左值和右值 C( 包括 C) 中所有的表达式和变量要么是左值&#xff0c;要么是右值。 通俗的左值的定义就是非临时对象&#xff0c;那些可以在多条语句中使用的对象&#xff0c;表达式结束后依然存在的持久化对象&#xff0c;所有的具名变量或者对象都是左值。右值是指临时的…

<Android开发> Android vold - 第一篇 vold前言简介

本次主要讲解存储模块如U盘等设备在android设备中的管理和使用的模块。本次主要基于android 8.1版本进行解析。不同android版本 vold的内容可能会有所差异。读者可对比阅读解析。 1 Vold介绍 Android中Vold是volume Daemon,即Volume守护进程;Android没有使用Linux平台下的ud…

泛型的介绍和使用方法

目录 一、泛型概述 二、泛型类 三、泛型接口 1.直接在实现类中确定好类型 2.实现类也写成泛型类 四、泛型方法 五、泛型好处 六、泛型集合 1.概念 2.特点 一、泛型概述 1. 本质是参数化类型&#xff0c;把类型作为参数传递。 2. 常见的形式有泛型类、泛型接口、泛型…

【虚幻引擎】UE4/UE5 后期处理盒子(PostProcessVolume)

一、简介 PostProcessVolume&#xff08;后期处理盒子&#xff09;&#xff1a;UE4非常强大的一个后期处理&#xff0c;可以调节画面的色彩&#xff0c;相机的景深&#xff0c;视频的输出效果&#xff0c;环境的光线构造&#xff0c;电影级的氛围感。 二、参数介绍 一、场景中…

驱动开发 Linux按键中断点灯

华清远见上海中心22071班 三个按键实现按键中断&#xff0c; key1->led1 key2->led2 key3->led3 按键按一下灯亮&#xff0c;再按一下灯灭 #include <linux/module.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/f…

外贸供应链ERP怎么选?全流程综合管理解析

随着外贸体制深入改革、进出口权放开等&#xff0c;以往处于垄断地位&#xff0c;享有种种优惠政策的外贸企业&#xff0c;将面临越来越严峻的国内外市场的竞争及各种挑战。长期以来形成的相对落后的管理体制和经营模式&#xff0c;严重地影响外贸企业在新形势下的生存和发展。…

m基于GA遗传优化+SA模拟退火的混合改进算法的多产品多机器生产优化matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 这里&#xff0c;我们首先介绍一下改进算法的基本原理&#xff0c;按照前面说的&#xff0c;这里我们主要将GA和SA进行合并。 这里&#xff0c;我研究了下&#xff0c;将两种算法做如下方法的结合…

Microcorruption 第一关 Tutorial

Microcorruptioin 第一关 Tutorial 首先进入Tutorial这一关&#xff0c;这是闯关页面。 在主函数设置断点&#xff0c;控制台输入"break main"或"b main"或手动点击反汇编栏中main函数的第一行设置断点。 该闯关游戏主要是破解密码&#xff0c;查看主函数…

前端开发免费资源分享

Fancy-Border-Radius 地址&#xff1a;https://9elements.github.io/fancy-border-radius/ 简介&#xff1a;在线编辑border-radius的可视化工具&#xff0c;通过调节可以很方便地帮我们生成想要的形状&#xff0c;然后直接复制下面的css代码&#xff0c;即可使用 Make some …

sCrypt 合约中的椭圆曲线算法:第二部分

我们在脚本中实现了椭圆曲线 (EC) 算法。在之前的实现中&#xff0c;我们进行链下计算并在脚本中验证结果。我们这里直接用脚本计算。 基于EC的应用非常多&#xff0c;特别是在密码学领域&#xff0c;如数字签名、加密、承诺方案等。作为具体示例&#xff0c;我们重新实现了 E…

11.28作业

实现对点灯所涉及函数的封装 1.头文件 #ifndef __GPIO_H__ #define __GPIO_H__ //结构体封装 typedef struct{volatile unsigned int MODER;volatile unsigned int OTYPER;volatile unsigned int OSPEEDR;volatile unsigned int PUPDR;volatile unsigned int IDR;volatile un…

Kotlin进阶指南 - 单元测试

为了减少一些功能繁琐的测试流程&#xff0c;单元测试是提升开发效率的有效方式之一 在早些年的时候我有记录过一篇 Android 使用单元测试&#xff0c;只不过当时更多的针对 Java 方面的单元测试&#xff1b;在使用 Kotlin 后&#xff0c;我发现单元测试有点不同&#xff0c;好…

Nacos注册中心和服务消费方式

目录 一&#xff0c;服务治理介绍 什么是服务治理&#xff1f; 常见的注册中心 二&#xff0c;nacos简介 三&#xff0c;搭建nacos环境 四&#xff0c;代码演示 五&#xff0c;基于Feign实现服务调用 什么是Feign Feign的使用 Feign参数传递 一&#xff0c;服务治理介…

全国心力衰竭日:重症心衰的黑科技——永久型人工心脏

今天是第8个“全国心力衰竭日”。近几年&#xff0c;中国逐渐老龄化&#xff0c;心衰则是老龄化面临的严峻问题。我国心衰患病率估计已达1.3%&#xff0c;至少有1000万心力衰竭患者。中国已成为世界上拥有最大心衰患者群的国家之一。心力衰竭作为大多数心血管疾病的终末阶段&am…

如何在 docker 容器使用 nginx 实现反向代理统一站点入口

在微服务架构下&#xff0c;我们会部署很多微服务来实现我们的系统。每个微服务会有不同的端口。而用户在访问我们的站点时希望通过统一的端口来访问所有的服务&#xff0c;因为在很多情况下用户只能通过 80 或者 443 端口访问外界服务。 这个时候我们就可以使用反向代理来实现…

云上“两地三中心”,中小企业都用得起的多保险灾备方案

在云时代&#xff0c;大部分中小型企业都奔跑在云上或是服务器托管公司。任何规模的数据中心服务中断都会让你的企业踩雷。据统计&#xff0c;80%的数据中心服务中断都是由服务器硬件造成的。 据万博智云不完全统计&#xff1a; 2021年3月&#xff0c;一场大火完全摧毁了OVH在…

[附源码]计算机毕业设计SpringBoot蛋糕购物商城

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

如何将pdf转word?这几个软件可以做到文档格式转换

我们在日常办公中使用较为频繁的就是pdf和word两种文件格式&#xff0c;pdf的兼容性较好&#xff0c;就算跨设备传输也不会出现乱码的情况&#xff1b;word文档可以直接进行编辑修改&#xff0c;各有各的好处。如果我们想对pdf的内容进行修改的话&#xff0c;就需要把pdf文件转…

优维低代码:Redirect 路由重定向If 条件渲染

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 连载…

Centos7扩容root分区

Background 安装centos7系统时&#xff0c;如果没有自定义分区&#xff0c;系统默认给root分配的空间只有50G&#xff0c;其他空间都分配给了你创建的普通用户/home目录。这里我们把home的空间匀出一部分给root。 1、首先要注意数据安全 备份home目录的数据 tar zcf /tmp/hom…