-
初始化阶段:Vue 会遍历 data 中的所有属性,使用
Object.defineProperty为每个属性添加 getter 和 setter。 -
依赖收集阶段:
- 当视图渲染时,会读取 data 中的属性,触发 getter 方法
- getter 方法会把当前的 Watcher(可以理解为视图的更新器)添加到该属性的依赖收集器(subs 数组)中
-
数据更新阶段:
- 当修改 data 中的属性时,会触发 setter 方法
- setter 方法会通知依赖收集器中的所有 Watcher
- 每个 Watcher 会触发对应的视图更新
这个机制让 Vue 实现了 "数据驱动视图" 的核心特性,开发者只需要关注数据变化,而不必手动操作 DOM。
如果用简单的代码来模拟这个过程,大概是这样的:
javascript
运行
// 模拟依赖收集器
class Dep {
constructor() {
this.subs = []; // 存储依赖
}
// 添加依赖
depend() {
if (window.target) {
this.subs.push(window.target);
}
}
// 通知更新
notify() {
this.subs.forEach(sub => sub.update());
}
}
// 模拟Watcher
class Watcher {
constructor(updateFn) {
this.updateFn = updateFn;
window.target = this; // 将当前watcher设置为全局目标
}
// 执行更新
update() {
this.updateFn();
}
}
// 模拟响应式处理
function defineReactive(obj, key, val) {
const dep = new Dep(); // 每个属性有一个依赖收集器
Object.defineProperty(obj, key, {
get() {
dep.depend(); // 收集依赖
return val;
},
set(newVal) {
if (newVal !== val) {
val = newVal;
dep.notify(); // 通知更新
}
}
});
}
这个简化的模型展示了 Vue 响应式系统的核心思想,实际的 Vue 实现会更复杂,但基本原理是一致的。