返回
前端基础夯实:手写实现Vue 2.x响应式原理
前端
2024-02-11 00:19:58
在前端开发领域,响应式编程是至关重要的一个概念,它能帮助开发者在数据发生变化时自动更新UI界面。而Vue 2.x作为一款优秀的MVVM框架,其响应式原理更是值得深入探究和掌握。
本文将带领你一步步手写实现Vue 2.x的响应式原理,让你对响应式编程有一个更透彻的理解。我们从官方文档入手,分析基本原理,再到实践实现,循序渐进,深入浅出。
官方文档释义
Vue.js官网对于响应式原理的解释非常清晰:
Vue.js 的响应式系统是基于JavaScript的Proxy和Object.defineProperty实现的,它劫持了对象的属性访问,从而在属性值发生改变时触发相应的回调函数。
基本原理
基于上面的释义,我们可以将响应式原理的基本步骤拆解为:
- 劫持对象属性访问: 通过Object.defineProperty对对象的属性进行劫持,当属性被访问时,会触发相应的getter函数。
- 收集依赖: 在getter函数中,收集当前组件所依赖的数据属性,并建立依赖关系。
- 触发更新: 当所依赖的数据属性发生改变时,触发其对应的setter函数,执行更新操作。
实践实现
下面我们来手写实现Vue 2.x的响应式原理:
// 1. 创建Observer类
class Observer {
constructor(data) {
this.data = data;
this.deps = [];
this.walk(data);
}
// 2. 遍历对象,对属性进行劫持
walk(data) {
for (let key in data) {
this.defineReactive(data, key);
}
}
// 3. 对属性进行劫持
defineReactive(data, key) {
let dep = new Dep();
let val = data[key];
Object.defineProperty(data, key, {
get() {
dep.addDep(this);
return val;
},
set(newVal) {
if (val === newVal) return;
val = newVal;
dep.notify();
},
});
}
}
// 4. 创建Dep类,管理依赖收集
class Dep {
constructor() {
this.subs = [];
}
// 5. 添加依赖
addDep(sub) {
this.subs.push(sub);
}
// 6. 通知依赖更新
notify() {
this.subs.forEach(sub => sub.update());
}
}
// 7. 创建Watcher类,管理组件更新
class Watcher {
constructor(vm, exp, cb) {
this.vm = vm;
this.exp = exp;
this.cb = cb;
this.update();
}
// 8. 更新视图
update() {
this.cb.call(this.vm, this.vm.data[this.exp]);
}
}
// 9. 对传入数据进行响应式化
export default function observable(data) {
if (typeof data !== "object" || data === null) {
return data;
}
return new Observer(data).data;
}
应用示例
const app = new Vue({
data() {
return {
message: "Hello Vue!",
};
},
render(h) {
return h("div", {
innerHTML: this.message,
});
},
});
app.$mount("#app");
SEO优化