参考vue3,手写一个响应式系统
手写一个响应式系统是一个复杂且有趣的任务,它涉及到很多Vue 3内部的核心概念,如Proxy、Reactive Effect、Dependency Tracking等。下面是一个简化的响应式系统的实现,以帮助你理解其基本原理。
// 创建一个存储所有响应式对象的WeakMap,用于依赖收集和触发更新
const targetMap = new WeakMap();
// 创建一个简单的依赖类
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (activeEffect) {
this.subscribers.add(activeEffect);
}
}
notify() {
this.subscribers.forEach((effect) => {
effect();
});
}
}
// 当前活动的Reactive Effect
let activeEffect = null;
// 创建一个响应式Effect函数
function effect(fn) {
const run = () => {
try {
activeEffect = run;
fn();
} finally {
activeEffect = null;
}
};
run();
return run;
}
// 创建一个将对象转换为响应式对象的函数
function reactive(obj) {
// 如果对象已经是响应式的,则直接返回
if (targetMap.has(obj)) {
return targetMap.get(obj);
}
const originalObj = obj;
const observed = new Proxy(originalObj, {
get(target, key, receiver) {
const dep = getDep(target, key);
dep.depend();
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
const dep = getDep(target, key);
dep.notify();
return result;
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key);
const dep = getDep(target, key);
dep.notify();
return result;
},
});
// 使用WeakMap存储原始对象和对应的依赖集合
targetMap.set(originalObj, observed);
return observed;
}
// 获取或创建一个对象的依赖集合
function getDep(target, key) {
let depMap = targetMap.get(target);
if (!depMap) {
depMap = new Map();
targetMap.set(target, depMap);
}
let dep = depMap.get(key);
if (!dep) {
dep = new Dep();
depMap.set(key, dep);
}
return dep;
}
// 使用示例:
const state = reactive({ count: 0 });
effect(() => {
console.log("Count changed:", state.count);
});
state.count = 1; // 触发effect函数,输出:Count changed: 1
这个简化的响应式系统实现了Vue 3中的核心功能,包括将对象转换为响应式对象、依赖收集和触发更新。当你修改响应式对象的属性时,所有依赖于该属性的effect函数都会被重新执行。这只是一个基本的实现,Vue 3的响应式系统还包含了许多其他功能和优化,如计算属性、watch、ref、toRefs等。
浙公网安备 33010602011771号