明天的明天 永远的永远 未知的一切 我与你一起承担 ??

是非成败转头空 青山依旧在 几度夕阳红 。。。
  博客园  :: 首页  :: 管理

Vue2/3 实现动态循环的select下拉框去重功能:

Posted on 2024-03-15 08:42  且行且思  阅读(134)  评论(0编辑  收藏  举报
需求:
    前面下拉框选择某个选项(如:1)了,
    后面的下拉框不能在有前面选中内容的该选项(即不能在出现1的下拉选项)
    【Vue 实现动态循环出的多个select 不能重复选择相同的数据】
    
    注:下面注释的都可以根据需求更改

 

代码

<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不能重复选择相同数据的功能。
———————————————————————————————————————————————————————————————————————————————

Vue 3 实现代码:

 <div v-for="(item, index) in tableData.list" class="form-div">
          <Row :gutter="10">
            <Col :span="6">
              <FormItem
                :name="['list', index, 'temqProjectid']"
                :rules="[{ required: true, message: '请选择项目', trigger: 'change' }]"
              >
                <Select
                  v-model:value="item.temqProjectid"
                  style="width: 100%"
                  :showSearch="true"
                  allow-clear
                  placeholder="请选择项目"
                >
                  <SelectOption
                    v-for="it in showCityList(item.temqProjectid)"
                    :value="it.value"
                    :key="it.value"
                    >{{ it.label }}</SelectOption
                  >
                </Select>
              </FormItem>
            </Col>
           
          </Row>
        </div>






 const selectList = ref([{ value: '' }]); // [{ value: '' }];
  let 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',
    },
  ];

  const showCityList = (val) => {
    //讲option的显示数据进行深拷贝
    let newList = JSON.parse(JSON.stringify(cityList));
    //alert(val);

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

    //过滤出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;
  };

 若下拉框未显示文本,显示了值,可以调整如下:

<Select
                  v-model:value="item.temqProjectid"
                  :options="showCityList(item.temqProjectid)"
                  :showSearch="true"
                  style="width: 100%"
                  allow-clear
                  placeholder="请选择项目"
                />