我们之前讲了vue源码的结构还有vue的数据怎么知道变化的,那么我们知道数据发生变化之后我们怎么去更新视图了。
视图那么大,到底更新哪块呢?总不能视图发生变化,我们就把所有的界面都更新一遍,这样太耗性能了,体验也非常的不好。
怎么做到谁用了哪个数据,哪个数据发生变化,对应视图更新
这里面有个比较专业的说法叫做依赖收集。
vue中会为每个数据都建一个依赖数组,因为一个数据可能被多处使用,所以要用数组管理起来。这样当这个数据发生变化的时候,我们就去对应的依赖数组里面,把每个依赖都通知一遍。
这样就知道哪块内容要更新了。
知道依赖收集的思想,那么我们在何时收集依赖,又该在何时通知依赖更新?
比较好的办法就是谁获取这个数据的时候我们进行收集依赖,也就是getter属性被触发的时候,这样就能做到谁用了这个数据我们就收集这个依赖。
当这个数据发生变化的时候会触发setter属性,那么我们就可以在setter中通知依赖更新。
把依赖收集到哪里
我们说要把每个数据都建立一个依赖管理器,把所有的依赖都给管理起来。那么就需要依赖管理器类来进行管理。
就是我们的Dep类。
代码如下:
export default class Dep {
static target: ?Watcher;
id: number;
subs: Array<Watcher>;
constructor () {
this.id = uid++
this.subs = []
}
addSub (sub: Watcher) {
this.subs.push(sub)
}
// 删除一个依赖
removeSub (sub: Watcher) {
remove(this.subs, sub)
}
// 添加一个依赖
depend () {
if (Dep.target) {
Dep.target.addDep(this)
}
}
// 通知所有依赖更新
notify () {
// stabilize the subscriber list first
const subs = this.subs.slice()
for (let i = 0, l = subs.length; i < l; i++) {
subs[i].update()
}
}
}