59 lines
1.2 KiB
JavaScript
59 lines
1.2 KiB
JavaScript
const targetMap = new WeakMap() // 用原始对象作为key,依赖映射作为value
|
||
|
||
function 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(effect)
|
||
}
|
||
|
||
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)
|
||
}
|
||
|
||
const product = new reactive({price: 5, quantity: 2})
|
||
|
||
let total = 0
|
||
let effect = ()=>{
|
||
total = product.price * product.quantity // price和quantity都被跟踪了
|
||
}
|
||
|
||
effect()
|
||
|
||
console.log(total);
|
||
product.quantity = 3
|
||
console.log(total);
|
||
product.price = 100
|
||
console.log(total); |