数据响应式原理 — Watcher 类与依赖收集
2023-11-16 12:40:02
导言
在上一篇文章中,我们探讨了 Vue.js 中数组响应式处理的机制,学习了如何使用 ES6 Proxy 来监听数组的变化并触发视图更新。本篇将继续我们的探索之旅,深入了解 Vue.js 数据响应式的核心机制——Watcher 类和依赖收集。
Watcher 类
Watcher 是 Vue.js 中一个强大的类,负责监视数据变化并触发相应的更新。每个 Watcher 实例都与一个特定属性相关联,当该属性的值发生变化时,Watcher 就会被触发。
创建 Watcher
Watcher 实例是在组件实例化过程中创建的,如下所示:
const watcher = new Watcher(vm, exprOrFn, cb, options);
其中,
vm
:组件实例exprOrFn
:要监视的数据属性或计算属性的表达式或函数cb
:当属性值发生变化时要调用的回调函数options
:可选配置,例如 lazy、deep、immediate 等
依赖收集
为了实现响应性,Vue.js 需要知道哪些属性会被 Watcher 使用,以便在这些属性值发生变化时触发 Watcher。这个过程称为依赖收集。
当创建一个 Watcher 时,Vue.js 会自动收集 Watcher 所依赖的属性,并将其保存在 Watcher 实例的 deps
数组中。这个过程是在 Watcher 的 get()
方法中进行的:
Watcher.prototype.get = function get() {
this.beforeGet();
let value;
try {
value = this.getter.call(this.vm, this.vm);
} catch (e) {
if (this.user) {
// 如果是用户 Watcher,则抛出错误
warn(`Failed to evaluate user watcher getter: ${this.getter}`, e);
} else {
// 否则,将错误信息存储在 Watcher 实例上
this.error = e;
}
} finally {
this.afterGet();
}
return value;
};
在 get()
方法中,会调用 getter
函数来获取属性值。在获取值之前和之后,都会调用 beforeGet()
和 afterGet()
方法,这两个方法负责收集依赖和清理依赖。
依赖更新
当属性值发生变化时,Vue.js 会通知所有依赖于该属性的 Watcher。Watcher 将自身添加到属性的依赖者列表中,从而建立了一种双向联系。当属性值发生变化时,属性会通知它的依赖者,依赖者就会触发更新。
应用更新
当 Watcher 被触发时,它将调用其回调函数。回调函数负责更新视图或执行其他必要的更新操作。
总结
Watcher 类和依赖收集是 Vue.js 数据响应式系统的重要组成部分。通过创建 Watcher 并收集依赖,Vue.js 能够有效地监视数据变化并触发相应的更新,从而实现高效的数据响应性。了解这些机制对于深入理解 Vue.js 底层原理至关重要。