iView框架Select组件

问题描述

先看看Select组件的意思:

简单来说,就是下拉选择,可以多选可以单选。如果是多选,绑定的数据就是数组,否则就是单个数据。

有个需求,在Vue中使用Select组件,支持多选,选择某一项,使它与其他项互斥。也就是说,假设这一项叫A,选择A时就必须移除选择的其他选项,而选择其他选项时可以多选不受限制。

本文将使用简单的伪代码描述逻辑,并不是直接就能用的代码。

代码实现

先给出一部分JS代码:

data(){
    return {
        // Select绑定的数组
        select_list: [],
        // 选项数组
        options_list: ['A', '选项2', '选项3', '选项4', '选项5']
    }
}

使用Select组件:

<Select v-model="select_list" multiple>
    <Option v-for="item in options_list" :value="item" :key="item"></Option>
</Select>

逻辑就是这样,现在来实现需求。当选择A的时候,需要移除其他选项,只保留A。

很容易想到使用watch实现这个逻辑,即用watch监视select_list,当选择了A时就移除其他选项,只保留A。

不妨试试,逻辑如下:

watch: {
    select_list: {
      handler(newVal) {
        console.log('执行');
        if (newVal.indexOf("A") > -1) {
          this.select_list = newVal.filter((item) => item == "A");
        }
      },
      deep: true,
    },
  },

看上去很完美。注意,这里并没有判断oldVal中是否含有A,需要另外处理,但由于这不是这里的重点所以不多说。

执行起来发现,虽然在点击A的时候,似乎可以正常把其他数据移走,但会出现这么个情况:

这仅仅是点击了一次A!

原因很简单,watch每次监视到select_list的变化就会执行,执行handler的时候修改了select_list,于是再次监视到selct_list的变化,再次触发执行,如此周而复始。虽然在UI上似乎看不出问题,但进行了大量的运算,消耗了性能。

说到底,在监视中修改被监视的数据,会导致无限地触发下去。不过,当然可以使用其他办法阻止下一次触发,但我觉得这样并不好。

不如这样,直接在Option上添加click事件监听函数:

<Select v-model="select_list" multiple>
    <Option v-for="item in options_list" :value="item" :key="item" @click="add(item)"></Option>
</Select>

这样,在add中判断item的值是不是A。如果是A,则修改select_list,再做其他的工作,就更容易了。注意,这里需要在click后面添加.native,因为Option是一个组件,不是普通标签。

猜你喜欢

转载自blog.csdn.net/weixin_45792464/article/details/125809881