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中找到依赖,并进行依赖事件触发

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