Links

浅析VueJs中data数据新增属性后视图不更新的底层原因

今天啊
不小心写了一个vue里常见的bug
这个表格我想做一个点击多选的效果
然后呢
我就需要给这个表格绑定的数据啊
每一行都加一个这个selected的属性
然后呢通过点击事件去切换这个属性
最后通过动态样式来展示哈
现在呢这行代码本身逻辑没什么问题
但是呢他就是没有效果打开
为什么呢
原因是啊
我先给他退保对他付的值后
去加的这个属性
这样的话呢
未有在底层
就不会给他建立这么一个观察
我们每次点击的时候数据是变了
但是页面没有更新
所以呢我们有两种方法
第一种方法我们就把这行代码
放在前面
我们让它(data)处理好了之后
再给它放到tableData里面
我们来试一下
大家看 这样就可以了
那这是为什么呢
为什么我们写在前边就可以了呢
我们先来看一下原码
我们从initData往下找
在这个方法的最后他会建立观察 大家看
把data传进去
我们点进去
然后呢在这
他会new一个Observer
在这个构造函数里边注意
他分了两种一种是数组
一种是普通对象
我们这个对他属于普通的对象嘛
所以他第一次会走这里
大看他在这
会给每一个属性去define一个reactive
这个方法之前啊我们也提到过
我们再来看一下
那这个方法里边 大家看 他会用get、set
拦截所有的属性
所以呢我们再回过来看
我们在尝试给tableData赋值的时候
其实会被他这个set拦截
在这里边呢
他除了会deep通知到他的water之外
注意这还有一个observe
也就是说他会把这个新值啊
重新建立观察
即便我们的新值是一个数组
大家看
我们的心只是一个数组的话呢
他还是会扭一个Observer
但是呢
在这里边
注意他有区分了
如果是数组的话呢他在这
会遍历
每一个元素去给他建立一个观察
这有点像递归了,又回到这了
最终还会走到observe
然后呢走到这个walk
所以呢
我们回过来先给他加一个selected属性
再去给他赋值就没有问题
那还有一种方法可能有同学也想到了
就是我们顺序不变还是在这
然后呢
我们不直接采用给他赋值的方法
用什么呢
this.$set 用这种方式
给谁复制呢
给obj selected的赋 一个false
这样也没有问题
我们来看一下
大家看这样也是可以的
那至于这个$set为什么可以
大家如果感兴趣的话呢
可以在这加一个debugger
然后呢走到这个$set方法里边
看看他是怎么写的