返回
从零入门剖析 Vue 响应式,90 行代码带你玩转数据绑定!
前端
2023-09-26 14:53:51
九十行代码手摸手带你透彻理解 Vue 响应式
在现代 Web 开发中,响应式数据绑定是一个非常重要的特性。它允许开发人员轻松地将数据与 UI 绑定在一起,从而实现数据的自动更新。Vue.js 是一个非常流行的前端框架,它内置了强大的响应式系统。在本文中,我们将通过不到 100 行代码,实现一个极小的响应式 Vue。在此过程中,希望读者能了解到 Vue 实例、响应式数据、watcher、dep 四者之间的关系;dep 何时、如何收集 watcher。
核心概念
Vue 实例
Vue 实例是 Vue 应用的核心。它负责管理数据、模板和视图。
响应式数据
响应式数据是 Vue 实例中的数据。当响应式数据发生变化时,Vue 会自动更新视图。
Watcher
Watcher 是 Vue 用来跟踪响应式数据变化的工具。当响应式数据发生变化时,Watcher 会触发对应的回调函数。
Dep
Dep 是 Vue 用来管理 Watcher 的工具。每个响应式数据都对应一个 Dep。当响应式数据发生变化时,Dep 会通知所有 Watcher。
实现一个极小的响应式 Vue
现在,我们来实现一个极小的响应式 Vue。
class Vue {
constructor(options) {
this.$data = options.data;
this.observe(this.$data);
}
observe(data) {
Object.keys(data).forEach(key => {
this.defineReactive(data, key, data[key]);
});
}
defineReactive(data, key, val) {
const dep = new Dep();
Object.defineProperty(data, key, {
get() {
dep.addWatcher(Dep.target);
return val;
},
set(newVal) {
if (val === newVal) return;
val = newVal;
dep.notify();
}
});
}
}
class Dep {
constructor() {
this.watchers = [];
}
addWatcher(watcher) {
this.watchers.push(watcher);
}
notify() {
this.watchers.forEach(watcher => watcher.update());
}
}
class Watcher {
constructor(vm, expr, cb) {
this.vm = vm;
this.expr = expr;
this.cb = cb;
Dep.target = this;
this.oldValue = this.get();
}
get() {
return this.vm.$data[this.expr];
}
update() {
const newValue = this.get();
if (newValue !== this.oldValue) {
this.cb(newValue, this.oldValue);
}
}
}
const vm = new Vue({
data: {
count: 0
}
});
vm.$watch('count', (newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`);
});
vm.$data.count++;
这个极小的响应式 Vue 可以实现基本的数据绑定功能。当 vm.$data.count
发生变化时,vm.$watch('count', ...)
中的回调函数会被触发。
总结
在这篇文章中,我们通过不到 100 行代码,实现了一个极小的响应式 Vue。在此过程中,希望读者能了解到 Vue 实例、响应式数据、watcher、dep 四者之间的关系;dep 何时、如何收集 watcher。