51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Vue3响应式原理的简单实现

Vue中响应式(拿reactive举例)实现其实是一系列的依赖收集,使用Proxy对传入的对象进行代理监听,返回处理好的代理对象。

//对象的响应式原理
class Depend {
    static activeReactiveFn = null
    static targetMap = new WeakMap()
    constructor() {
        this.reactiveFns = new Set()
    }
    //封装一个获取depend的函数
    static getDepend(target, key) {
        //根据target对象获取map的过程
        let map = Depend.targetMap.get(target)
        if (!map) {
            map = new Map()
            Depend.targetMap.set(target, map)
        }
        //根据key获取depend对象
        let depend = map.get(key)
        if (!depend) {
            depend = new Depend()
            map.set(key, depend)
        }
        return depend
    }

    depend() {
        if (Depend.activeReactiveFn) {
            this.reactiveFns.add(Depend.activeReactiveFn)
        }
    }

    notify() {
        this.reactiveFns.forEach(fn => {
            fn()
        })
    }




}


//封装一个响应式函数
function watchFn(fn) {
Depend.activeReactiveFn = fn
fn()
Depend.activeReactiveFn = null;
}


function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
const dep = Depend.getDepend(target, key)
dep.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver)
const dep = Depend.getDepend(target, key)
dep.notify()
},
})
}


//对象的响应式
const obj = reactive({
name: 'kano',
age: 18
})


const foo = reactive({
bar: 111
})


watchFn(() =\> {
console.log('obj.name, obj.age---', obj.name, obj.age);
})
watchFn(() =\> {
console.log('obj.age---', obj.age);
})


watchFn(() =\> {
console.log('foo.bar---', foo.bar);
})

`// objProxy.name = 'sadada'
obj.age = 999
foo.bar = 'ds'`

getDepend 实际上设置了一个依赖树,如图所示:

obj对应一个weakMap,通过读取weakMap的key(目标对象),获取到对应的属性map,再从属性map中找到依赖,并进行依赖事件触发

赞(0)
未经允许不得转载:工具盒子 » Vue3响应式原理的简单实现