前端业务开发中不管使用vue2~3,还是react,angular各种前端技术栈,经常会遇到这种业务。一个下拉框Select中,不仅需要需要支持远程模糊搜索,还需要支持多选。并且在编辑时,还能正常把已经多选好的内容回显到Select中。
用Vue3+ElementPlus+TS举一个简单的案例。其他技术栈思路是一致的
新增时的逻辑
这一步和普通操作没有什么区别
<template><el-selectv-model="selectValue"multiplefilterableremotereserve-keywordplaceholder="请搜索并选择内容":remote-method="remoteMethod"style="width: 240px"><el-optionv-for="item in options":key="item.value":label="`${item.value}-${item.label}`":value="item.value"/></el-select>
</template>
<script lang="ts" setup>
let selectValue = ref([]);
let options = ref<{value: string;label: string;}[]
>([]);
const remoteMethod = (value: string) => {// 模拟远程接口查询// 一般远程模糊搜索的接口都带分页,如果数据为10万条,模糊搜索时肯定一次不能查10万条,还是需要正产分页的setTimeout(() => {options.value = [{value: "1",label: "张三",},{value: "2",label: "李四",},{value: "3",label: "王五",},];}, 200);
};</script>
多选OK的效果
编辑需要回显时的逻辑(关键点)
当这个下拉框在编辑页时,需要把同样已经多选的内容完整回显到这个下拉框中,因为数据本身就是多选,接口还是是分页的,回显时肯定不能使用接口查询功能来回显数据。因此,el-select的:value绑定就不应该只绑定value了。
<template><el-selectv-model="selectValue"multiplefilterableremotereserve-keywordplaceholder="请搜索并选择内容":remote-method="remoteMethod"style="width: 240px"><!--value直接也把label绑定上--><el-optionv-for="item in options":key="item.value":label="`${item.value}-${item.label}`" :value="`${item.value}-${item.label}`"/></el-select>
</template>
<script lang="ts" setup>
let selectValue = ref([]);
let options = ref<{value: string;label: string;}[]
>([]);
const remoteMethod = (value: string) => {};
onMounted(() => {// 模拟编辑页初始化的时候接口初始化赋值逻辑// 编辑页面查询到多选的详情信息dataconst data = [ { value: "1", label: "张三", }, { value: "2", label: "李四", }, ]; selectValue.value = data.map(item => `${item.value}-${item.label}`); //['1-张三', '2-李四'];
});
</script>
这时候selectValue的绑定时就不仅仅是value了,而是这样的格式。这样就不需要通过后端接口来实现多选内容的数据回显了。
['1-张三', '2-李四']
编辑操作时剔除label内容
当前selectValue的绑定值已经是“[‘1-张三’, ‘2-李四’]”这样了,编辑操作确定提交数据时剔除-label就行。
const originalArray = ['1-张三', '2-李四']; const numericArray = originalArray.map(item => { // 使用split('-')分割字符串,并取第一个元素(即数字部分) const numberPart = item.split('-')[0]; // 将字符串转换为数字 return parseInt(numberPart, 10);
}); console.log(numericArray); // 输出: [1, 2]。编辑确定操作时,入参给接口就行。
如果业务需求的label展示值不是
:label="`${item.value}-${item.label}`"
这种形式,而是只展示名称label,不需要对应value
:label="`${item.label}`"
这样的形式,有空我在把另一种思路加上。未完待续…