vue.js设计与实现(四)-响应系统

1、简单的响应架构设计实现:
背景:有一个函数effect实现document.body.innerText的文本内容改变,body中的文本内容和一个data对象中的text属性相互绑定,当data对象中text属性改变时,body中的文本做出相应的改变;
设计原理:采用Proxy代理data数据,当代理对象获取到data属性text时,将effect函数放置一个桶中,即一个new Set() 的数据结构中,当代理对象改变data中的数据时,去遍历执行Set结构中的函数对象,从而达到更改body文本中的目的;

    const data = {text:'hello world'}
    const bucket = new Set();
    const obj = new Proxy(data,{
        get(target,key){
            bucket.add(effect)
            return target[key]
        },
        set(target,key,newVal){
            target[key] = newVal
            bucket.forEach(fn=>fn())
            return true
        }
    })
    function effect(){
        document.body.innerText = obj.text
    }
    // 触发读取操作
    effect()
    // 1秒后修改
    setTimeout(()=>{
        obj.text = 'hello vue3'
    },1000)

完善结构处理:

const data = {text:'hello world'}
    const bucket = new WeakMap()
    // 定义一个全局变量用来存储被注册的副作用函数
    let activeEffect;
    // 用来注册副作用函数
    function effect(fn){
        activeEffect = fn;
        fn()
    }
    function track(target,key){
        if(!activeEffect) return
        let depsMap = bucket.get(target)
            if(!depsMap){
                bucket.set(target,depsMap = new Map())
            }
            let deps = depsMap.get(key)
            if(!deps){
                depsMap.set(key,deps = new Set())
            }
            deps.add(activeEffect)
    }
    function trigger(target,key){
        const depsMap = bucket.get(target)
        if(!depsMap) return
        const effects = depsMap.get(key)
        effects && effects.forEach(fn=>fn())
    }
    const obj = new Proxy(data,{
        get(target,key){
            track(target,key)
            return target[key]
        },
        set(target,key,newVal){
            target[key] = newVal
            trigger(target,key)
        }
    })
    effect(
        ()=>{
            // console.log('effect run',bucket)
            document.body.innerText = obj.text;
        }
    )
    setTimeout(()=>{
        obj.notExist = 'hello vue3'
    },1000)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容