也就是说,依赖到某个数组的Watcher
(就是读取了数组的Watcher
)最终也会被添加到数组下所有被observer
了的对象和数组的依赖列表里面。为什么要这样做呢???
首先,我要验证一下我的理解是不是正确的。
验证我对源码的理解
我在computed
函数中用到了this.list
,这样这个computed
对应的Watcher
会进入list
属性对应的dep
中。并且按照代码的意思,这个Watcher
也会进入空对象{}
对应的observer
的dep
中,我们来找一找有没有这个Watcher
:
确实有这个Watcher
,那么vue
为什么要这样设计呢?
这样做的原因
尤雨溪其实在这个位置有注释:
:::tips
Collect dependencies on array elements when the array is touched, since
we cannot intercept array element access like property getters.
:::
当这个数组元素被访问的时候,收集数组各元素的依赖,因为我们更不能像get函数一样拦截数组元素的访问。
试想一下,当我们的computed
是这样的:
data() {
return {
list: [{}],
};
},
computed: {
objKeyLength() {
return Object.keys(this.list[0]).length;
},
},
这个computed
如果没有dependArray
的加持会将这个computed
对应的watcher
实例添加到哪些dep
列表中呢?
:::info
其实这里就触发了**list**
属性的**get**
函数,所以只会将**watcher**
收集到**defineReactive**
函数闭包中的**dep**
和**this.list**
数组对应的**observer**
实例的**dep**
中。由于数组并没有对数组元素进行**defineReactive**
的改造,所以这里Vue根本监听不到我们访问索引**0**
位置对应的数组元素的行为。
也就是说,如果我们对**this.list[0].obj**
的key进行增加或者删除,这个**watcher**
应该更新吗,答案是肯定的。但是如果没有**dependArray**
的执行,他是不会更新的。因为当执行我上述描述的操作实际是触发的**obj**
对象对应的**observer**
实例中的**dep**
属性的**notify**
操作,也就是说,只有位于**obj**
对应的**observer**
实例的**dep**
列表中的**watcher**
才会触发**update**
操作。**dependArray**
就是做的这样一件事儿,将这个**watcher**
添加到各个数组元素的**dep**
列表中(也就是添加到数组元素对应的**observer**
实例的**dep**
属性中)。
:::