1

目标

实现 vue-next 响应式模块中的两个 API : reactiveeffect

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
}

xuan241
41 声望1 粉丝