通过 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
相似问题