Vue2中element-ui中select框无法选中的问题
这个问题是在工作中发现的,其实也是个比较常见的问题,问题出现的情况是这样的:
带选择框的主要页面代码是这样的
1 | //html |
1 | //vue-data |
可以看到这个select框是复用的,current改变的时候,改变select框中v-model的绑定值,因为这个current的数量和值是不确定的,所以办法在定义selectValue的时候在里面定义好出现的值,需要在从后台请求到相应的数据后再进行赋值,然后就发生了,修改current的值之后,select框里面的值无法选择,选择以后,select里面的选中值也不变。
出现这个问题的主要原因是,vue2中的双向绑定机制是不完美的,因为selectValue在初始化的时候,内部是没有值的,vue2中的双向绑定是在初始化的时候去劫持data中的每个值,为每个值添加一个dep类(用来发送消息),然后去收集页面上跟这个值有关的地方,为每个地方添加一个watcher类(用来接收消息)去订阅这个值的dep类。这样就可以在某个值变化的时候,通过dep类去给所有订阅这个dep类的watcher类发送消息,然后再调用watcher类中的更新函数,去更新页面视图。
这样就出现了一个问题,selectValue是一个对象,在他内部新增值的时候,新增的值是没有添加dep类的(因为是在初始化的时候添加的,初始化的时候这个新增的值还不存在),所以也不存在收集到的watcher类。所以这个值变化的时候,页面上是不会有显示的,但是这个值是已经相应的变化了,就是说这个新增的值不是双向绑定的。所以就会出现select框里面的值在页面上看起来是无法选择的(因为值变了页面不变)。
同类的问题很常见,在其他组件中将组件的值绑定到一个对象后期新增的属性上,也会发现页面和值不是实时绑定的。为了解决这个问题,vue2中提供了一个$set的函数,具体用法如下:
1 | //就用上面的值举例子 |
可以看到,$set一共有三个参数,第一个是需要新增/改变值的对象,第二个是这个对象要新增/改变的值的key,第三个是这个对象要新增/改变的值的value。
它的基本逻辑就是首先会去判断第一个参数是不是vue实例data中的值;然后去判断第二个值的key是不是已经存在了,如果存在的话,就直接赋值改变,如果不存在的话,就劫持这个值的setter和getter,监听这个值并且收集相应的依赖(简单来说就是对这个值再进行一下初始化,这样的话,后续这个值变化的时候,页面就可以相应的变化)
