动态下拉框的去重(基于vue element)

4,494 阅读2分钟

产品经理经常有这样的需求,每个下拉框的值不能重复,如下图所示,当第一个下拉框选择了黄金糕,第二个就不能选了。 demo示例地址 codepen.io/taxilng/pen…

<template>
    <div>
        <div v-for="(sfb, index) in mulConditions" :key="index" label-width="50px">
            <el-select multiple collapse-tags clearable size="small" v-model="sfb.arr" @change="initOption" placeholder="请选择">
                <el-option v-for="item in options[index]" :key="item.value" :label="item.label" :value="item.value"></el-option>
            </el-select>
            <i class="el-icon-circle-plus add_remove_icon" @click="add()" v-if="mulConditions.length < 6"></i>
            <i class="el-icon-remove add_remove_icon" @click="minus(index)" v-show="mulConditions.length > 1"></i>
        </div>
    </div>
</template>

<script>
const initOptions = [{
    value: '选项1',
    label: '黄金糕'
}, {
    value: '选项2',
    label: '双皮奶'
}, {
    value: '选项3',
    label: '蚵仔煎'
}, {
    value: '选项4',
    label: '龙须面'
}, {
    value: '选项5',
    label: '北京烤鸭'
}]
export default {
    data () {
        return {
            options: [], // 保存了每个下拉框的option,因此是个数组
            mulConditions: [{ // 所有下拉框选择的值的集合
                arr: []
            }],
        }
    },
    created () {
        this.options[0] = JSON.parse(JSON.stringify(initOptions)) // 首先初始化,第一个下拉框的值
    },
    methods: {
        // 新增一个下拉框
        add () {
            this.mulConditions.push({
                arr: []
            })
            // 初始化所有的下拉框的值,因为新增的下拉框是需要排除掉之前选中的值的
            // 例如第一个已经选择了黄金糕,那么新增的第二个就不能有了
            this.initOption()
        },
        // 删除一个下拉框
        minus (index) {
            this.mulConditions.splice(index, 1); //删除数组中指定一项,vue的数组变异方法
            this.initOption();// 初始化所有的下拉框的值,因为删除了一项,就要把选中的值释放出来
        },
        // 核心代码
        // 当下拉框选择时触发,新增和删除下拉框也会触发
        initOption () {
            // 首先遍历所有已经选中的值
            this.mulConditions.forEach((_, i) => {
                // 假设遍历到第一个, i = 0
                const totalOtherChoose = this.mulConditions
                    .filter((_, idx) => idx !== i) //过滤出除了第一项的剩余的数组集合
                    .reduce((total, cur) => [...total, ...cur.arr], []); 
                    //用reduce 将他们的值集合起来,例如第二项选了黄金糕,第三项选了双皮奶,那么值就是
                    ['黄金', '双皮奶']
                const unChooseArr = initOptions.filter(
                 // 先通过new Set().has()方法判断是否存在
                 // 如果有了,则返回false,这样就过滤掉
                 // 那么他剩下的就是所有未选中的
                    x => !new Set(totalOtherChoose).has(x.value)
                );
                // 把未选中的所有下拉选项重新复制给 第一项
                this.options[i] = unChooseArr;
            });
        },
    },
};
</script>