背景
在《深入浅出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用完之后都会还原,为什么要维护一个栈结构呢?
疑问
