Vue 3.0 reactive/effect
reactive.js:
import { isObject } from "../utils";
import { track, trigger } from "./effect";
export function reactive(target) {
// 判断 target 类型
// 如果是基本类型,则不将其转化成响应式
if (!isObject(target)) return target;
const proxy = new Proxy(target, {
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver);
// 收集依赖
track(target, key);
return res;
},
set(target, key, value, receiver) {
const res = Reflect.get(target, key, value, receiver);
// 触发依赖
trigger(target, key);
return res;
}
});
return proxy;
}
effect.js:
// 记录当前正在执行的副作用函数 let activeEffect; /** 难点 * 一个副作用函数可能依赖多个响应式数据 * 一个响应式数据更新可能会触发多个副作用函数 * 因此 targetMap 的结构是: * { * [target]: { * [key]: [] * } * } * 使用 WeakMap 是因为不需要手动删除不需要的依赖 */ const targetMap = new WeakMap(); export function effect(fn) { const effectFn = () => { try { activeEffect = effectFn; return fn(); } finally { // todo } } effectFn(); return effectFn; } export function track(target, key) { if (!activeEffect) return; let depsMap = targetMap.get(target); // 初始化时一定是不存在的 if (!depsMap) targetMap.set(target, (depsMap = new Map())); let deps = depsMap.get(key); // 同样,初始化的时候一定无值 if (!deps) depsMap.set(key, (deps = new Set())); deps.add(activeEffect); console.log(targetMap, key) } export function trigger(target, key) { const depsMap = targetMap.get(target); if (!depsMap) return; const deps = depsMap.get(key) if (!deps) return; deps.forEach(effectFn => { effectFn(); }); }
index.js(入口文件):
import { reactive } from "./reactive/reactive";
import { effect } from "./reactive/effect";
const observed = reactive({
count: 0
});
effect(() => {
console.log(observed.count)
})

浙公网安备 33010602011771号