vue3响应式设计-v1简单版

76 阅读1分钟

实现最简单的响应式设计

  1. 注册副作用函数
  2. 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