浅析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方法里边

看看他是怎么写的

最后更新于