大家好,新人一个,初次写博客还请大家多多关照。
对于Vue的响应式,想必大家都有所了解,在Vue响应式数据中,computed 是比较特殊的响应式数据,它们可以监听使用到的 数据,数据 改变 computed 的数据也会重新计算。
今天主要是讨论 computed 实现原理 。 computed 在内部主要是运用 Watcher 和 Dep 构造函数进行收集依赖和派发更新。
咱们先来看看 Watcher 和 Dep 源码。
var uid = 0;
/**
* dep 就是用来给每个数据做个标记,可以用来收集数据和派发更新
*/
var Dep = function Dep () {
this.id = uid++;
//给每一个 Dep 打一个标记。这里需要说明一下,vm中data的每个数据进行初始化的时候都会调用this.dep = new Dep(),每一个数据都会有dep属性。
//(通过Observer 构造函数进行数据初始化,这里就不多说了,大家感兴趣可以看一下源码)
this.subs = []; // 这个subs收集的是watcher,派发更新的时候遍历每个watcher调用update方法
};
Dep.prototype.addSub = function addSub (sub) {
this.subs.push(sub);//这个方式是用来收集watcher的(每个computed构建出来的Watcher实例)
};
Dep.prototype.depend = function depend () {
if (Dep.target) {
Dep.target.addDep(this); // 这里的方法是Watcher原型上的addDep方法,请看下面
}
};
Watcher.prototype.addDep = function addDep (dep) {
var id = dep.id;
if (!this.depIds.has(id)) {
this.depIds.add(id); //将依赖的每个dep,添加到 watcher 的 deps集合中,完成数据的收集
this.depIds.push(dep);
}
};
Dep.prototype.notify = function notify () {
// 用来出发watcher的更新,每当数据改变,每个数据的dep就会出发