指标
实现 vue-next 响应式模块中的两个 API : reactive
、 effect
var obj = reactive({ name: 'Vic', haha: { num: 0 }})effect(() => { console.log('打印消息:obj.name', obj.name)}) effect(() => { console.log('打印消息:obj.haha.num', obj.haha.num)})obj.name = 'qiu'obj.haha.num = 9// output Vic// output 0// output qiu// output 9
代码实现
const targetMap = new WeakMap()let activeEffect = nullconst handlers = { get(target, key, receiver) { const res = Reflect.get(target, key, receiver) tarck(target, key) return typeof res === 'object' ? reactive(res) : res }, set(target, key, value, receiver) { const res = Reflect.set(target, key, value, receiver) trigger(target, key) return res }} function reactive(target) { return new Proxy(target, handlers)}function tarck(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())) if (!deps.has(activeEffect)) deps.add(activeEffect)}function trigger(target, key) { targetMap.get(target).get(key).forEach(fn => fn())}function effect(fn) { activeEffect = fn fn() activeEffect = null}