返回
**Vue源码解读—手摸手教你实现一个简单Vue(3):dep和watcher的编写**
前端
2023-09-27 02:34:47
前言
在上一篇文章中,我们实现了Observer,这一篇文章我们就来讲讲Dep和Watcher的实现。依然如前,在文章末尾我编写了一个js的简单测试版供你边测试边读懂这一节的文字。
一、Dep的实现
Dep是一个类,它的作用是收集Watcher,当数据发生变化时,通知Watcher更新。
class Dep {
constructor() {
this.subscribers = [];
}
addSubscriber(watcher) {
this.subscribers.push(watcher);
}
notify() {
this.subscribers.forEach(watcher => {
watcher.update();
});
}
}
二、Watcher的实现
Watcher是一个类,它的作用是当数据发生变化时,更新视图。
class Watcher {
constructor(vm, expr, cb) {
this.vm = vm;
this.expr = expr;
this.cb = cb;
// 在实例化的时候,立刻计算expr的值,并将其作为初始值
this.value = this.get();
}
get() {
// 将当前的Watcher实例添加到Dep中,以便在数据发生变化时通知它
Dep.target = this;
const value = compileUtil.getValue(this.vm, this.expr);
Dep.target = null;
return value;
}
update() {
const value = this.get();
// 对比新的值和旧的值是否发生了变化,如果变化了,则调用cb
if (value !== this.value) {
this.cb(value, this.value);
this.value = value;
}
}
}
三、测试
我们可以在浏览器中创建一个简单的Vue实例来测试Dep和Watcher的实现。
const vm = new Vue({
data: {
a: 1
}
});
vm.$watch('a', (newValue, oldValue) => {
console.log(`a的值从${oldValue}变为${newValue}`);
});
vm.a = 2;
运行这段代码,你将在控制台看到如下输出:
a的值从1变为2
这表明我们的Dep和Watcher已经正确地实现了。
总结
在这一篇文章中,我们实现了Dep和Watcher,并通过一个简单的测试实例验证了它们的正确性。希望这篇文章能帮助你更好地理解Vue3的响应式原理。