前端业务开发中不管使用vue2~3,还是react,angular各种前端技术栈,经常会遇到这种业务。一个下拉框Select中,不仅需要需要支持远程模糊搜索,还需要支持多选。并且在编辑时,还能正常把已经多选好的内容回显到Select中。

用Vue3+ElementPlus+TS举一个简单的案例。其他技术栈思路是一致的

情况1

把label和value同时当绑定值

新增时的逻辑

这一步和普通操作没有什么区别

<template>
    <el-select
        v-model="selectValue"
        multiple
        filterable
        remote
        reserve-keyword
        placeholder="请搜索并选择内容"
        :remote-method="remoteMethod"
        style="width: 240px"
    >
        <el-option
            v-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-select
        v-model="selectValue"
        multiple
        filterable
        remote
        reserve-keyword
        placeholder="请搜索并选择内容"
        :remote-method="remoteMethod"
        style="width: 240px"
    >
        <!--value直接也把label绑定上-->
        <el-option
            v-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(() => {
    // 模拟编辑页初始化的时候接口初始化赋值逻辑
    // 编辑页面查询到多选的详情信息data
    const 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]。编辑确定操作时,入参给接口就行。

情况2

只把value当绑定值(正常都是这种形式)

新增时的逻辑

和情况1基本一致,只是label绑定项只给展示label值就行

<template>
    <el-select
        v-model="selectValue"
        multiple
        filterable
        remote
        reserve-keyword
        placeholder="请搜索并选择内容"
        :remote-method="remoteMethod"
        style="width: 240px"
    >
        <el-option
            v-for="item in options"
            :key="item.value"
            :label="`${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的效果

在这里插入图片描述

编辑需要回显时的逻辑(情况2关键点)

<template>
    <el-select
        v-model="selectValue"
        multiple
        filterable
        remote
        reserve-keyword
        placeholder="请搜索并选择内容"
        :remote-method="remoteMethod"
        style="width: 240px"
    >
        <el-option
            v-for="item in options"
            :key="item.value"
            :label="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) => {};
onMounted(() => {
    // 模拟编辑页初始化的时候接口初始化赋值逻辑
    // 编辑页面查询到新增时保存的多选的详情信息data
    const data = [
        {  
            value: "1",  
            label: "张三",  
        },  
        {  
            value: "2",  
            label: "李四",  
        }, 
    ];  
    // selectValue绑定值赋值回显
    selectValue.value = data.map((v) => v.value); // ['1', '2'];
    // 直接用查询到的接口data数据赋值到options上,这样多选下拉框就能回显出张三,李四了。用户需要在此模糊搜索时也不影响。
    options.value = data;
    // 如果需要二次重置options,也不影响。
});
</script>