ElementUI はドロップダウン リストに検索を実装します

分析:

ここに画像の説明を挿入

  1. まず、上の図の効果を実現する必要があります。次に、Element-UI に el-select がないため、自分で記述する必要があります。
  2. el-popoverコンポーネントを使用し、それを使用してv-model="visible"コントロール ディスプレイを実現する必要があります。
  3. 私たちは1つを置くel-popoverためにここにいますslot="reference" el-select
    • popper-append-to-body="false"フローティング要素を挿入する必要はありませ
    • popper-class="hide-popper"定義フローティング ウィンドウ クラスを として使用しhide-popper
      display:none存在しないel-selectドロップダウン オプションが選択されるように設定します。
    • el-option下で選択したリストの要素をループして、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フォーカスされているかどうかを取得し、 focused にするために使用します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. selectedel-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'
    			}
    		]
    	}
    }
    }
    

おすすめ

転載: blog.csdn.net/qq_40591925/article/details/128084179