Vue 实现动态循环出的多个select 不能重复选择相同的数据

  • 前言
  • 效果图演示
  • 实现逻辑
  • 代码
  • 总结


前言

1.本篇文章功能的实现是基于vue的计算属性computed
2.个人感觉vue的计算属性computed挺适合做这个功能的,因为通过计算属性return的值可以保证相对独立,又可以在其依赖的属性的值发生变化时进行重新计算。
3.是偶然间想到用计算属性来完成这个功能,怕自己忘了所以写在博客这里当总结,同时也希望笔者的想法能给大家带来一点启发

效果图演示

实现下拉框的去重

实现逻辑

(具体的实现逻辑我写在了代码的注释里了,这里就写下核心的逻辑)
1.保证每个下拉框的Option循环的cityList都是独立的,不会影响到其他的下拉框
2.把所有Select已经选中的选项放入一个数组arr中
3.所有的Option的显示数据cityList,需要保留当前自己Select选中的选项,再去除在arr中已经有的选项

代码

<template>
  <div id="app">
    <div v-for="(item,index) in selectList" :key="index">
      <Select v-model="item.value" style="width:200px">
        <Option
          v-for="it in showCityList(item.value)"
          :value="it.value"
          :key="it.value"
        >{{ it.label }}</Option>
      </Select>
      <Button icon="md-add-circle" @click="listAdd()"></Button>
      <Button icon="md-trash" @click="listDelete()"></Button>
    </div>
  </div>
</template>
data() {
    return {
      selectList: [{ value: "" }],
      cityList: [
        {
          value: "New York",
          label: "New York"
        },
        {
          value: "London",
          label: "London"
        },
        {
          value: "Sydney",
          label: "Sydney"
        },
        {
          value: "Ottawa",
          label: "Ottawa"
        },
        {
          value: "Paris",
          label: "Paris"
        },
        {
          value: "Canberra",
          label: "Canberra"
        }
      ]
    };
  },
methods: {
    listAdd() {
      if (this.selectList.length < this.cityList.length) {
        this.selectList.push({
          value: ""
        });
      } else {
        console.log("不能再加啦");
      }
    },
    listDelete(index) {
      this.selectList.splice(index, 1);
    }
  },
computed: {
    showCityList() {
      return (val) => {
        //讲option的显示数据进行深拷贝
        let newList = JSON.parse(JSON.stringify(this.cityList));

        //处理selectList数据,返回一个新数组arr
        //arr数组就相当于所有Select选中的数据集合(没有选中的为'',不影响判断),只要在这个集合里面,其他的下拉框就不应该有这个选项
        const arr = this.selectList.map(item => {
          //将其格式{value:'NewYork'}变成['NewYork'],方便使用indexOf进行判断
          return (item = item.value);
        });

        //过滤出newList里面需要显示的数据
        newList = newList.filter(item => {
          //当前下拉框的选中的数据需要显示
          //val就是当前下拉框选中的值
          if (val == item.value) {
            return item;
          } else {
            //再判断在arr这个数组中是不是有这个数据,如果不在,说明是需要显示的
            if (arr.indexOf(item.value) == -1) {
              return item;
            }
          }
        });

        //返回Options显示数据
        return newList;
      };
    }
  }

在整个showCityList中,唯一的变量就是selectList,只要selectList的值有改变,就会触发计算属性的重新计算,这样就可以保证无论是Select选中某个选项,还是增加下拉框,或者删除下拉框都会让每个下拉框对应的Option中的newList进行重新生成,从而达到多个select不能重复选择相同数据的功能。