【Vue2】详解 Vue2 响应式原理
Vue2 的响应式原理主要依赖于以下几个核心组件:
Observer
: 它会递归地遍历 data 对象的属性,并使用Object.defineProperty
为它们设置 getter 和 setter。这样一来,一旦属性的值被访问或者改变,就能够触发依赖的收集和更新。Dep
: 它是一个依赖收集器,每个属性都有一个Dep
实例来收集所有依赖于这个属性的Watcher
。Watcher
: 它是一个跟踪属性变化并执行相应回调的类。组件的渲染函数和计算属性都会创建Watcher
。Directives
: Vue 中的指令,如v-model
和v-if
,会创建Directive
实例,这些实例会在相应的 DOM 事件中执行依赖的属性更新。
以下是一个简化的响应式系统的示例代码:
class Vue {
constructor(options) {
this._data = options.data;
observe(this._data, this);
new Compiler(options.el, this);
}
}
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
class Watcher {
constructor(vm, exp, cb) {
this.vm = vm;
this.exp = exp;
this.cb = cb;
this.value = vm._data[exp]; // 添加依赖
}
update() {
const newValue = this.vm._data[this.exp];
if (newValue !== this.value) {
this.cb(newValue);
}
}
}
function defineReactive(obj, key, val, vm) {
const dep = new Dep();
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
dep.addSub(Dep.target); // 添加依赖
return val;
},
set: function reactiveSetter(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 触发更新
}
});
}
function observe(data, vm) {
if (typeof data !== 'object' || data === null) {
return;
}
Object.keys(data).forEach(key => {
defineReactive(data, key, data[key], vm);
});
}
// 假设的编译器部分
class Compiler {
constructor(el, vm) {
this.el = document.querySelector(el);
this.vm = vm;
this.compile(this.el);
}
compile(node) {
// ...
}
bind(node, directive) {
// ...
}
}
// 使用 Vue 类
const vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
这个示例代码提供了响应式系统的基本框架,并没有包含实际的编译器实现细节。在实际的 Vue 应用中,Compiler
类会遍历 DOM 元素,处理指令,并根据指令和数据绑定更新 DOM。
评论已关闭