el-select不能选择已经选过的项

这篇博客讨论了如何在前端实现检验项目的唯一性验证,通过监听el-select组件的change事件,结合Vue的计算属性和自定义验证规则,确保用户不会选择已添加过的检验项目。同时,介绍了如何在数据变更时更新表单状态,并动态应用不同的验证规则。

       <div class="add-line-border">
          <div
            class="add-line"
            v-for="(item, key) in itemoForm.item_list"
            :key="key"
          >
            <el-form-item
              :label="'检验项目' + (key + 1) + ':'"
              :prop="'item_list.' + key + '.item_id'"
              :rules="ruleList"
            >
              <div class="add-content">
                <div class="add-msg">
                  <el-select
                    @change="currentSel($event, key)"
                    v-model="item.item_id"
                    placeholder="请选择"
                    clearable
                  >
                    <el-option
                      v-for="ii in inspectionItems"
                      :key="ii.id"
                      :label="ii.itemName"
                      :value="ii.id"
                    >
                    </el-option>
                  </el-select>
                </div>
                <div class="add-options" @click="delItemOption(key)">删除</div>
              </div>
            </el-form-item>
          </div>
        </div>

 在data中设置rule,和isSelect值

    rule1: [
        {
          required: true,
          message: '请选择检验项目',
          trigger: 'change',
        },
      ],
      rule2: [
        {

          message: '已经添加过该检验项目啦',

        },
      ],

      isSelect:false,

在compute中计算ruleList的值

  computed: {
    ruleList: function () {
      if (this.isSelect) {
        return this.rule2;
      } else {
        return this.rule1;
      }
    },
  },

在methods方法中

   //判断该选项值是否已经选择过
    count(arr, val) {
      return arr.filter((e) => e.item_id === val).length;
    },
   //el-select的change事件
   currentSel(e, k) {  
      let count = this.count(this.itemoForm.item_list, e);
      if (count > 1.5) {
        //已经选过该值了,触发对应的验证规则
        this.isSelect = true;
        this.$refs['itemForm'].validateField(`item_list.${k}.item_id`)
      } else {
        this.isSelect = false;
        //将选项值存到数组中
        for (let i = 0; i < this.inspectionItems.length; i++) {
          if (this.inspectionItems[i].id == e) {
            this.itemoForm.item_list[k].item_title = this.inspectionItems[i].itemName;
            this.itemoForm.item_list[k].item_type = this.inspectionItems[i].itemType;
          }
        }
      }
    },

 如果选择已经选过的数据会提示

   

 

 

<think>我们正在处理一个关于Vue2中el-select组件的问题:change事件触发但无法选中下拉。 根据引用资料,有几个可能的原因和解决方案: 1. **事件绑定错误**:可能错误地绑定了事件或者使用了错误的事件名(如@Change而不是@change)。Vue是大小写敏感的,在模板中事件名应该使用kebab-case(短横线分隔)命名。引用[5]中使用了`@Change`,但在HTML中属性名不区分大小写,通常建议使用全小写。不过,在Vue中,我们通常使用`@change`。 2. **初始化时触发**:引用[3]和[4]提到,change事件可能在初始化时就被触发,导致一些意外行为。引用[3]指出,如果错误地监听了其他事件(比如可能监听了input事件),可能会在初始化时触发多次。正确的方式是使用`@change`事件,并且确保只在用户选择时触发。 3. **使用`@click.native`替代**:引用[2]提到,他们通过使用el-option的`@click.native`事件来替代el-select的change事件,因为change事件有时不能触发或者触发时值为undefined。 4. **数据更新问题**:引用[1]中使用了`this.$set`来确保响应式更新,因为直接给对象赋值可能不会触发视图更新。如果是因为数据没有正确更新导致视图没有刷新,那么使用`this.$set`可以解决。 5. **异步问题**:引用[1]中在change事件中执行了异步操作,然后更新数据。如果异步操作导致更新延迟,也可能出现视图未及时更新的问题。 针对用户的问题“change事件触发但无法选中下拉”,可能的原因和解决方案如下: - **原因1:事件绑定不正确** 解决方案:确保使用`@change`(全小写)绑定事件。 - **原因2:change事件处理函数中可能有错误,导致未正确设置值** 解决方案:检查事件处理函数,确保没有错误,并且正确设置了绑定的v-model的值。 - **原因3:v-model绑定的值在父组件中是props传递的,没有正确使用.sync或emit更新** 解决方案:如果el-select在子组件中,并且v-model绑定的是props,那么不能直接修改,需要emit事件让父组件更新。 - **原因4:数据未响应式更新** 解决方案:如果更新的是对象或数组的某个属性,确保使用Vue.set或this.$set来更新,以确保响应式。 - **原因5:下拉选的key重复或value类型问题** 解决方案:确保el-option的key是唯一的,并且value的类型与v-model绑定的值类型一致(比如都是字符串或都是数字)。 根据引用资料,我们可以尝试以下具体方法: 方法一:使用`@click.native`在el-option上(引用[2]) ```html <el-select v-model="value"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" @click.native="handleClick(item.value)"> </el-option> </el-select> ``` 方法二:检查change事件处理函数,确保正确设置值,并使用this.$set(引用[1]) 在change事件处理函数中,如果更新的是对象属性,使用this.$set。 方法三:检查事件名是否为`@change`(全小写),并且处理函数接受一个参数(即选中的值) ```html <el-select v-model="value" @change="handleChange"> ``` 在methods中: ```javascript methods: { handleChange(val) { // val就是选中的值 // 直接设置this.value = val 是不必要的,因为v-model会自动更新 // 如果还需要做其他操作,在这里进行 } } ``` 方法四:如果是因为初始化时触发导致的问题,可以设置一个标志位,在mounted之后才允许执行change事件。 方法五:检查v-model绑定的值是否在data中正确初始化,并且确保el-option的value与v-model类型匹配。 由于用户没有提供具体代码,我们只能给出一般性的解决方案。如果上述方法仍不能解决,可能需要检查是否有其他代码干扰,如自定义指令、混入等。 下面我们按照要求生成相关问题:</think>在 Vue2 中使用 `el-select` 组件时,遇到 change 事件触发但无法选中下拉的问题,通常由以下原因及解决方案: ### 常见原因及解决方案 1. **事件绑定错误** - **问题**:使用了错误的事件名(如 `@Change` 而非 `@change`)或错误标签(如误用 `@input`) - **解决**:确保使用 **`@change`** 并绑定到 `el-select` 而非 `el-option` ```html <!-- 正确示例 --> <el-select v-model="selectedValue" @change="handleChange"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> </el-select> ``` 2. **初始化时意外触发** - **问题**:组件初始化时自动触发 change 事件,干扰后续操作[^3][^4] - **解决**: - 添加标志位控制首次不执行逻辑 ```javascript data() { return { isFirstLoad: true } }, methods: { handleChange(val) { if (this.isFirstLoad) { this.isFirstLoad = false; return; } // 正常逻辑 } } ``` 3. **异步数据未更新** - **问题**:异步操作未使用 `$set` 导致视图未更新[^1] - **解决**:使用 **`this.$set`** 或 Vue 响应式 API ```javascript async handleChange(val) { const res = await fetchData(); // 错误: this.formData.value = res.value this.$set(this.formData, 'value', res.value); // ✅ 正确 } ``` 4. **值类型不匹配** - **问题**:`v-model` 绑定值与 `el-option` 的 `value` 类型不一致(如数字 vs 字符串) - **解决**:统一数据类型 ```html <!-- 确保 value 类型一致 --> <el-option :value="Number(item.id)" ... /> <!----> <el-option :value="String(item.id)" ... /> ``` 5. **嵌套组件通信问题** - **问题**:在子组件中直接修改父组件传递的 prop - **解决**:通过 `$emit` 通知父组件修改 ```javascript // 子组件 this.$emit('update:selected', newValue); // 父组件 <child-component :selected.sync="parentValue" /> ``` ### 其他优化建议 - 使用 **`@click.native`** 作为备选方案(需绑定到 `el-option`)[^2]: ```html <el-option @click.native="handleClick(item.value)" ... /> ``` - 检查是否有重复的 **`key`** 导致渲染异常 - 使用 **`.sync` 修饰符** 简化父子组件双向绑定 ### 完整示例 ```html <template> <el-select v-model="selectedValue" @change="handleSelectChange" clearable > <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </template> <script> export default { data() { return { selectedValue: null, options: [{ id: 1, name: '选1' }, { id: 2, name: '选2' }], isMounted: false // 防止初始化触发 }; }, mounted() { setTimeout(() => this.isMounted = true, 100); // 延迟标记加载完成 }, methods: { async handleSelectChange(val) { if (!this.isMounted) return; // 跳过初始化触发 // 异步操作示例 const res = await this.$api.fetchData(val); this.$set(this.form, 'data', res); // 确保响应式更新 } } }; </script> ``` 通过检查事件绑定方式、数据响应性、异步处理逻辑和值类型匹配,通常可解决 change 事件触发但未选中的问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值