Proxy 模拟实现Vue3响应式

37 阅读1分钟
//Weakmap👉map👉{fn}

//用类存储方法
class depend{
    constructor(){
        this.dependfn = []
    }
    adddepend(fn){
        this.dependfn.push(fn)
    }
    notify(){
        this.dependfn.forEach(element => {
            element()
        });
    }
}

//在get调用时存入依赖方法
let SaveWatchFn = null
function WatchFn(fn){
    SaveWatchFn = fn ;
    fn() ;
    SaveWatchFn = null ;
}

//收集响应式
let WatchWeakMap = new WeakMap()
function SaveProxyMap(target,key){
    let objmap = WatchWeakMap.get(target)
    if(!objmap){
        objmap = new Map()
        WatchWeakMap.set(target,objmap)
    }
    let KeyDependFn = objmap.get(key)
    if(!KeyDependFn){
        KeyDependFn = new depend()
        objmap.set(key,KeyDependFn)
    }
    return KeyDependFn
}
let yui = {
    name:"yui",
    age:16
}

let yuiproxy = new Proxy(yui,{
    get: function (target,key,receiver) {
        let keyDepenfn = SaveProxyMap(target,key)
        keyDepenfn.adddepend(SaveWatchFn)
        return Reflect.get(target,key,receiver)
    },
    set: function (target,key,newvalue,receiver) {
        //先代理改变再执行响应方法
        Reflect.set(target,key,newvalue,receiver)
        console.log('set---------------------------')
        let keyDepenfn = SaveProxyMap(target,key)
        keyDepenfn.notify()
    }
})

WatchFn(function (){
    console.log(yuiproxy.name)
})
WatchFn(function (){
    console.log('name改变'+ yuiproxy.name)
})
WatchFn(function (){
    console.log(yuiproxy.age)
})
WatchFn(function (){
    console.log('age改变'+ yuiproxy.age)
})
yuiproxy.age = 1