const targetMap = new WeakMap() // 用原始对象作为key,依赖映射作为value let activeEffect = null // 保存当前的需要订阅通知的effect function track(target, key) { if(activeEffect) { let depsMap = targetMap.get(target) if(!depsMap) { targetMap.set(target, (depsMap = new Map())) } let dep = depsMap.get(key) if(!dep){ depsMap.set(key, (dep=new Set())) } dep.add(activeEffect) // 将efect添加进通知set } } function trigger(target, key) { const depsMap = targetMap.get(target) if(!depsMap) return const deps = depsMap.get(key) deps.forEach(effect => { effect() }); } function reactive(target){ const hander = { get(target, key, receiver) { const result = Reflect.get(target, key, receiver) track(target, key) return result }, set(target, key, value, receiver) { let oldValue = target[key] let result = Reflect.set(target, key, value, receiver) if (oldValue !== value){ trigger(target, key) } return result } } return new Proxy(target, hander) } // 创建ref,为基本数据类型赋予响应式功能 function ref(raw) { const r = { get value(){ track(r, 'value') return raw }, set value(newVal){ raw = newVal trigger(r, 'value') } } return r } function effect(effect){ activeEffect = effect activeEffect() activeEffect = null } function computed(getter){ let result = ref() effect(()=>(result.value = getter())) return result } const product = new reactive({price: 5, quantity: 2}) const total = computed(()=>{ return product.price * product.quantity }) console.log(total.value); product.price = 3 console.log(total.value); product.quantity = 10 console.log(total.value);