通过 Vue.set 设置对象 一个新的属性时所发生的事情
来源:4-10 检测变化的注意事项

aznmoe
2020-02-13
老师你好,这里我打断点的时候 有点乱,不能理清,我从代码角度去理解下这个过程你看看对不对。
Vue.set
函数 可以直接简化为以下两个语句
defineReactive(ob.value, key, val);
ob.dep.notify();
假设 vm._data
为 {msg: {a: 'aaa'}}
,那么在初始化完毕后,vm._data
与 vm._data.msg
都会被 new Observe()
即 两者都会有一个 __ob__
属性。 且 vm._data.msg
通过 childOb.dep.depend()
使 vm._data.msg.__ob__.dep.subs
收集了 当前的 渲染watcher
- 一般情况下
vm._data.msg.a = 'newValaaa'
时,其会直接 触发vm._data.msg.a
所持有的dep.notify
。也就是上两节课所讲的内容。 Vue.set(vm._data.msg, 'b', 'bbb')
时,这个时候在Vue.set
函数内部执行vm._data.msg.__ob__.dep.notify
去。为什么要这样?
因为vm._data.msg.b
在没有被defineReactive
过呢还(等下说Vue.set
里面那个defineReactive
),我们只能退而求其次,让vm._data.msg.b
的父级vm._data.msg
去notify
。因为vm._data.msg.__ob__.subs
含有当前的 渲染watcher
,随后便可 成功的渲染新的页面了。
提问: 如果 我们能在Vue.set
函数中 拿到vm
实例的话,是不是 我们直接vm._data.__ob__.dep.notify
理论上也能完成更新?
回过头来说 Vue.set
函数中 defineReactive(ob.value, key, val);
作用,其作用其实很简单,就是为 vm._data.obj
的 新属性 弄成响应式的,但其还未被读取过,也就是说 这个属性 所持有的 dep.subs 数组为空
总结下,我的观点是 childOb.dep.depend()
是 为 vm._data
下的 每一个层级的对象 做一个依赖收集,这个收集的目的是 好 手动 dep.notify
去,然后 用到这个的就是 Vue.set
,所有老师说 childOb.dep.depend()
就是 为 Vue.set
而准备的
1回答
-
你理解的没有问题,先为你点赞。
提问: 如果 我们能在 Vue.set 函数中 拿到 vm 实例的话,是不是 我们直接 vm._data.__ob__.dep.notify 理论上也能完成更新?
是的,但是不如 ob.dep.notify() 更直观,先定义成响应式,再主动触发响应式对象依赖的通知。012020-02-14
相似问题