vue
源码中defineReactive
中监听数据的有段代码如下:
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
if (Dep.target) {
dep.depend()
}
return value
}
})
我的理解是:vue
先进行初始化,在这个过程中methods
、生命周期
...初始化完成并设置data
的setter
和getter
。
但是在初始化的过程中是没有进行依赖收集的,因为这个时候并不知道哪些数据是有用的。
初始化完成之后会进行一次render
在这个过程中会读取到data
中一些有用到的数据,因为在初始化的时候设置了getter
所以就会触发依赖收集,也就是上面代码的dep.depend()
所以在我理解这个Dep.target
就是用来区别是初始化阶段还是render
阶段,然后才判断是否进行依赖收集。
以上是我的一些想法,因为看了源码还是没能理解这个Dep.target
的作用,然后查询了一些文章结合自己的理解做出了以上总结,如果有误或者不准确的地方,烦请各位大佬提出并解释。
Vue的初始化比较复杂,以下探讨的范围只是在Vue对数据响应式过程
将 data 进行响应式的过程原理通过 defineProperty 将对象(先不考虑数组的情况)所有的属性都定义成 getter setter 的形式,然后读取数据的时候就会触发getter,修改数据的时候就会触发setter,这样,Vue就有能力被读取数据的时候做一些事情,比如说,是谁在读取数据。
举例就是,比如说一个组件,组件在渲染时候需要读取 data.foo ,那么就会触发 foo的getter,而Vue在这个过程中做的事情就是 将组件保存到全局唯一的位置,比如说挂载到类的静态属性(Dep.target)上,然后会触发foo的getter,此时通过调用 dep.depend() ,将这个组件保存到 foo 属性的依赖列表中 dep,当以后修改foo的值时,就会触发 foo的 setter,那么此时就可以 通知foo的依赖列表foo, “我的值变了,你们需要重新再来读取一下”。
准确的来说,data 进行响应式以后会变成 Observer 类型,然后上文的使用组件来举例依赖也不太准确,只是为了方便理解,Vue实际上是使用Watcher 类来作为依赖,这个类封装了一些通用的方法。
以上