用element-plus+vue3+ts实现搜索下拉框
element_plus+vue3+ts
·
<template>
<div class="search_select_body">
<el-select
v-model="currentOption"
placeholder="请选择"
popper-class="select_box"
:multiple="multipleOpt"
@change="changeSelect"
@visible-change="showOrHidden"
@remove-tag="removeTag"
>
<div class="search_input_box">
<el-input v-model="searchKey" placeholder="请输入搜索内容" @input="confirmSearch" />
</div>
<el-option v-for="(item, index) in memberOption" :key="index" :label="item.name" :value="item.id"
><span v-if="item.id" class="diy_check"></span>{{ item.displayname }}</el-option
>
</el-select>
</div>
</template>
<script lang="ts">
import { defineComponent, toRefs, reactive, computed, toRef, ref } from 'vue';
interface Idata {
optionData: any[];
multipleOpt: boolean;
}
interface Ioption {
//这里要看你要传进来的是什么数据,根据实际情况而定
name: string;
id: string;
}
export default defineComponent({
props: {
optionData: {
type: Array,
default() {
return [];
},
require: true,
},
multipleOpt: {
type: Boolean,
default: true,
require: true,
},
},
emits: ['deliverVal', 'deliverKeyword'],
//默认值和重置在父组件中用ref来设置
setup(props: Idata, context) {
const state = reactive({
searchKey: '', //搜索框输入的值
});
let currentOption: any = ref([]); //选中的值,单选为字符串,多选为数组
const confirmSearch = (val: string | number) => {
if (val !== '') {
context.emit('deliverKeyword', val.toString());
}
};
const { optionData, multipleOpt } = toRefs(props);
if (!multipleOpt.value) {
currentOption.value = '';
}
const memberOption = computed(() => {
//选项值根据父组件传过来的值进行属性计算得出,这里因为业务需求写的复杂了些,可根据你的实际情况而修改
let searchOption = [] as Ioption[];
if (optionData.value.length) {
optionData.value.forEach((item: any) => {
searchOption.push({
name: item.displayname,
id: item.id,
});
});
}
return searchOption.length ? searchOption : ['']; //无论单选还是多选,这里需要一个默认的空值来控制输入框显示(element-plus的el-select组件只有有值才能渲染el-select标签内部的dom节点)
});
const changeSelect = (val: string[] | string) => {
if (memberOption.value.length == 1 && memberOption.value[0] == '') {
currentOption.value = multipleOpt.value ? [] : ''; //选第一个空值的时候做的处理
}
};
const showOrHidden = (val: boolean) => {
if (!val) {
//多选遍历后传值,单选直接传选中值
if (multipleOpt.value) {
multiChangeVal();
} else {
context.emit('deliverVal', currentOption.value);
}
}
};
const removeTag = () => {
//此方法主要是给父组件用,用于删除选项时再次把最新的值传给父组件
multiChangeVal();
};
const multiChangeVal = () => {
//多选的时将值传给父组件
let result = [] as any[];
memberOption.value.forEach((item: any) => {
currentOption.value.forEach((items: string) => {
if (items === item.id) {
result.push({
name: item.displayname,
id: item.id,
});
}
});
});
context.emit('deliverVal', result);
};
return {
confirmSearch,
...toRefs(state),
memberOption,
changeSelect,
showOrHidden,
currentOption,
removeTag,
};
},
});
</script>
<style scoped lang="less">
.search_select_body {
position: relative;
.search_input_box {
position: absolute;
top: 44px;
left: 0;
z-index: 3000;
}
}
</style>
<style>
</style>
更多推荐
已为社区贡献4条内容
所有评论(0)