0
点赞
收藏
分享

微信扫一扫

vue3的响应式实现原理

晴儿成长记 2022-01-08 阅读 67
vue.js前端

vue3的响应式是基于proxy的。

class Dep{
    constructor(){
        this.subscriber = new Set()
    }

    // addEffect(effect){
    //     this.subscriber.add(effect)
    // }


    depend(){
        if(activeEffect) {
            this.subscriber.add(activeEffect)
        }
    }

    notify(){
        this.subscriber.forEach(effect => {
            effect()
        })
    }
}


let activeEffect = null;

function watchEffect(effect){
    // dep.addEffect(effect)

    activeEffect = effect;
    // dep.depend();
    effect();
    activeEffect = null;


}


const targetMap = new WeakMap()

function getDep(target, key){
    let depsMap = targetMap.get(target)
    if(!depsMap) {
        depsMap = new Map();
        targetMap.set(target, depsMap)
    }


    let dep = depsMap.get(key);
    if(!dep) {
        dep = new Dep();
        depsMap.set(key, dep)
    }


    return dep
}


function reactive(raw){
    return new Proxy(raw, {
        get(target, key) {
            const dep = getDep(target, key)
            dep.depend();
            return target[key]
        },
        set(target, key, newValue) {
            const dep = getDep(target, key);
            target[key] = newValue;
            dep.notify()
        }
    })
}





let info = reactive({name: 'coderwhy', age: 18, counter: 100})
let foo = reactive({height: 1.88});


// const dep = new Dep()

watchEffect(function (){
    console.log(info.counter * 2, info.age)
})

watchEffect(function (){
    console.log(info.counter * info.counter)
})

watchEffect(function (){
    console.log(foo.height)
})


// info.counter++;
// foo.height = 2

// dep.notify()
info.age++


举报

相关推荐

0 条评论