1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
let activeEffect = null
function effect(eff) { activeEffect = eff activeEffect() activeEffect = null }
const targetMap = new WeakMap()
function track(target, key) { if (activeEffect) { console.log("track", target, key) 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) } }
function trigger(target, key) { console.log("trigger", target, key) const depsMap = targetMap.get(target) if (!depsMap) { return } let dep = depsMap.get(key) if (dep) { dep.forEach((effect) => { effect() }) } }
function reactive(target) { const handler = { get(target, key, receiver) { let 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, handler) }
function ref(raw) { const r = { get value() { track(r, "vlaue") }, set value(newVal) { if(raw !== newVal){ raw = newVal trigger(r, "value") } }, } return r }
function computed(getter) { let result = ref() effect(() => (result.value = getter())) return result }
let product = reactive({ price: 5, quantity: 2 }) let total = 0
effect(() => { total = product.price * product.quantity })
console.log(total) product.quantity = 3 console.log(total)
|