vue.js設(shè)計與實現(xiàn)(四)-響應(yīng)系統(tǒng)

1、簡單的響應(yīng)架構(gòu)設(shè)計實現(xiàn):
背景:有一個函數(shù)effect實現(xiàn)document.body.innerText的文本內(nèi)容改變,body中的文本內(nèi)容和一個data對象中的text屬性相互綁定,當data對象中text屬性改變時,body中的文本做出相應(yīng)的改變;
設(shè)計原理:采用Proxy代理data數(shù)據(jù),當代理對象獲取到data屬性text時,將effect函數(shù)放置一個桶中,即一個new Set() 的數(shù)據(jù)結(jié)構(gòu)中,當代理對象改變data中的數(shù)據(jù)時,去遍歷執(zhí)行Set結(jié)構(gòu)中的函數(shù)對象,從而達到更改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
    }
    // 觸發(fā)讀取操作
    effect()
    // 1秒后修改
    setTimeout(()=>{
        obj.text = 'hello vue3'
    },1000)

完善結(jié)構(gòu)處理:

const data = {text:'hello world'}
    const bucket = new WeakMap()
    // 定義一個全局變量用來存儲被注冊的副作用函數(shù)
    let activeEffect;
    // 用來注冊副作用函數(shù)
    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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容