實現 vue-next 響應式模塊中的兩個 API : reactive
、 effect
vue
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 = null const 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 }