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


    分析:

    在这里插入图片描述

    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">
      		
      		<el-popover
      		v-model="visible"
      		placement="bottom-start"
      		width="auto"
      		>
      		<div slot="reference" class="check-select">
      			
      			<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>
      		
      		<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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
    • 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()
      		}
      	}
      	}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113
      • 114
      • 115
      • 116
      • 117
      • 118
      • 119
      • 120
      • 121
      • 122
      • 123
      • 124
      • 125
      • 126
      • 127
      • 128
      • 129
      • 130
      • 131
      • 132
      • 133
      • 134
      • 135
      • 136
      • 137
      • 138
      • 139
      • 140
      • 141
      • 142
      • 143
      • 144
      • 145
      • 146
      • 147
      • 148
      • 149
      • 150
      • 151
      • 152
      • 153
    • 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);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
    • 使用

      <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'
      			}
      		]
      	}
      }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    • 相关阅读:
      150.逆波兰表达式求值
      智慧工地4G+蓝牙+GPS/北斗RTK人员定位系统解决方案
      优优嗨聚集团:OTC药品能否纳入报销成为各方关注焦点,对OTC医疗有何影响
      Flink CDC-SQL Server CDC配置及DataStream API实现代码...可实现监控采集一个数据库的多个表
      Spring Boot Admin2 AdminServerAutoConfiguration详解
      R 语言data.frame 中的另一行中减去一行
      常用设计模式——策略模式
      Bridging nonnull in Objective-C to Swift: Is It Safe?
      leetcode 343 整数拆分
      selenium多窗口、多iframe切换、alert切换
    • 原文地址:https://blog.csdn.net/qq_40591925/article/details/128084179