背景
在《深入浅出Vue.js》这本书中,收集依赖的时候,是从window.target
这个位置中收集依赖的。但是阅读源码之后,其实发现Vue.js
是从Dep.target
上收集和挂载依赖的。所以window.target
和Dep.target
有什么区别呢?
答疑
Dep.target
其实是Dep
类的一个静态属性:
class Watcher{
static target: ?Watcher;
}
其实充当的作用跟window.target
一样一样的。他是一个中专站,用来暴露Watcher
实例,以便其他位置收集这个实例。
这里,Vuejs
维护了一个target
的数组:targetStack
:
const targetStack = [];
export function pushTarget (_target: Watcher) {
if (Dep.target) targetStack.push(Dep.target)
Dep.target = _target
}
export function popTarget () {
Dep.target = targetStack.pop()
}
当Watcher
调用get
方法收集依赖的时候,首先要将自己挂载到Dep.target
上,完成这一步是通过调用pushTarget
方法:
:::info
pushTarget
方法先将当前Dep.target
备份进数组中,然后再让Dep.target
指向指定的Watcher
。
:::
当收集完依赖后,我们需要将Dep.target
还原,也就是还原到之前的状态,这时,我们需要在Watcher
中调用:popTarget
方法,使target
还原成之前的状态。
其实我有一事不明,为什么Vuejs
要维护一个栈结构呢?既然每次Watcher
用完之后都会还原,为什么要维护一个栈结构呢?
疑问