背景

在《深入浅出Vue.js》这本书中,收集依赖的时候,是从window.target这个位置中收集依赖的。但是阅读源码之后,其实发现Vue.js是从Dep.target上收集和挂载依赖的。所以window.targetDep.target有什么区别呢?

答疑

Dep.target其实是Dep类的一个静态属性:

  1. class Watcher{
  2. static target: ?Watcher;
  3. }

其实充当的作用跟window.target一样一样的。他是一个中专站,用来暴露Watcher实例,以便其他位置收集这个实例。
这里,Vuejs维护了一个target的数组:targetStack

  1. const targetStack = [];
  2. export function pushTarget (_target: Watcher) {
  3. if (Dep.target) targetStack.push(Dep.target)
  4. Dep.target = _target
  5. }
  6. export function popTarget () {
  7. Dep.target = targetStack.pop()
  8. }

Watcher调用get方法收集依赖的时候,首先要将自己挂载到Dep.target上,完成这一步是通过调用pushTarget方法: :::info pushTarget方法先将当前Dep.target备份进数组中,然后再让Dep.target指向指定的Watcher。 ::: 当收集完依赖后,我们需要将Dep.target还原,也就是还原到之前的状态,这时,我们需要在Watcher中调用:popTarget方法,使target还原成之前的状态。


其实我有一事不明,为什么Vuejs要维护一个栈结构呢?既然每次Watcher用完之后都会还原,为什么要维护一个栈结构呢?
疑问