美文网首页
vue.js设计与实现(四)-响应系统

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

作者: 幸宇 | 来源:发表于2022-12-28 18:55 被阅读0次

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)

相关文章

网友评论

      本文标题:vue.js设计与实现(四)-响应系统

      本文链接:https://www.haomeiwen.com/subject/isdzqdtx.html