实现最简单的响应式设计
- 注册副作用函数
- proxy代理数据
// 用一个全局变量存储被注册的副作用函数
let activeAffect;
// 用于注册副作用函数
function effect(fn) {
activeAffect = fn;
// 执行副作用函数。会触发依赖的数据的get方法,从而触发track依赖收集
fn();
}
// 用一个全局变量存储响应式数据的依赖关系
let bucket = new WeakMap();
function proxy(data) {
return new Proxy(data, {
get(target, key) {
// 追踪
track(target, key);
return target[key];
},
set(target, key, newVal) {
target[key] = newVal;
// 触发
trigger(target, key);
return true;
},
});
}
// 对target对象的key属性进行副作用函数的依赖收集
function track(target, key) {
if (!activeAffect) return;
let depsMap = bucket[target];
if (!depsMap) {
bucket.set(target, (depsMap = new Map()));
}
let deps = depsMap[key];
if (!deps) {
depsMap.set(key, (deps = new Set()));
}
deps.add(activeAffect);
}
// 触发数据绑定的所有副作用函数
function trigger(target, key) {
const depsMap = bucket.get(target);
if (!depsMap) return;
const effects = depsMap.get(key);
if (!effects) return;
effects.forEach((fn) => {
fn();
});
}
// 测试:
let obj = { foo: 1, bar: 2 };
let proxyObj = proxy(obj);
let eff = effect(() => {
let res = proxyObj.foo + proxyObj.bar;
console.log(res);
});
proxyObj.foo++;
// 日志输出:
// 3
// 4