溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue3響應(yīng)式Proxy與Reflect如何使用

發(fā)布時間:2022-08-04 11:12:35 來源:億速云 閱讀:152 作者:iii 欄目:開發(fā)技術(shù)

這篇“vue3響應(yīng)式Proxy與Reflect如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue3響應(yīng)式Proxy與Reflect如何使用”文章吧。

    理解Proxy與Reflect

    vue3的響應(yīng)式離不開Proxy,說到Proxy則離不開Reflect.這兩個對象是ES6新增的對象,同時在編程領(lǐng)域,他們也代表著2種設(shè)計模式,即代理與反射。

    Proxy

    Proxy 可以理解成,在目標(biāo)對象之前架設(shè)一層“攔截”,外界對該對象的訪問,都必須經(jīng)過這層攔截,而我們就可以通過這層攔截去改變目標(biāo)對象的內(nèi)容或者行為,或者叫過濾和控制。這個詞本意就是代理,好比一個代理人站在神奇,我們所有行為都會被他過濾,可能我們說的話,經(jīng)過代理人一說,意思就變了。

    ES6 原生提供 Proxy 構(gòu)造函數(shù),用來生成 Proxy 實例。

    var proxy = new Proxy(target, handler);

    其中target表示要代理的那個對象,handler則是表示我們需要攔截的行為,這里直接放一張阮一峰的截圖。

    vue3響應(yīng)式Proxy與Reflect如何使用

    Reflect

    Reflect中文譯為:反射。如果說Proxy 是有一個代理人站在身前面,幫你攔截并處理一些行為,那么Reflect就是你身后的一面鏡子,它能看見真實的自己。

    而你自己,就是一個類或者對象,或者一個函數(shù),只要是js中存在的,都能被ProxyReflect處理。

    vue3響應(yīng)式Proxy與Reflect如何使用

    它的操作和Proxy正好相反,但卻一一對應(yīng)。比如我們獲取對象中一個屬性。

    const obj = {foo:1}
    const a = Reflect.get(obj, 'foo')

    這一小節(jié)主要是介紹了Proxy與Reflect,后面會有一個應(yīng)用老告訴你為什么Proxy與Reflect與響應(yīng)式數(shù)據(jù)息息相關(guān)。

    實踐示例

    看完了ProxyReflect的基本使用之后,我們實踐一下。

    我們曾經(jīng)寫過這樣的代碼

    const reactive = (object)=>{
        return new Proxy(object,{
           get(target,key){
             track(target,key)
             return target[key]
           }
           set(target,key, newVal){
               target[key] = newVal
               trigger(target,key)
               return true
           }
        })
    }

    其實就是用Proxy代理了對象讀和取操作,在讀的時候收集依賴,在取的時候觸發(fā)響應(yīng)??雌饋硭坪鯖]有問題,那么我們再試?yán)^續(xù)往下寫

    const obj = {
        a:1,
        get b(){
          return this.a
        }
    }
    const data = reactive(obj)
    effect(()=>{
        console.log(data.b)
    })
    setTimeOut(()=>{
        data.b++
    },500)

    這里我們沒有用一般的對象寫法,而是通過訪問器為它新增了一個b屬性.之后,我們先把這個對象轉(zhuǎn)換為響應(yīng)式對象,再給他們設(shè)定一個響應(yīng)式的回調(diào),然后在冬天改變他的值,理論上這時候應(yīng)該會執(zhí)行副作用函數(shù),但是實際上呢,根本不會執(zhí)行。

    我們回顧一下之前寫的reactive方法,在里面返回的是target[key],當(dāng)我們的target是obj,key是b的時候,那個this會是誰呢?因為target是原始對象,也就是obj,根據(jù)誰調(diào)用是誰的原則,這個this也就指向了obj。obj是響應(yīng)式對象嗎,顯然不是,那個b也就永遠(yuǎn)不會執(zhí)行副作用函數(shù),響應(yīng)式就失效了。

    這里其實就是this的指向問題,你可能會說一般人怎么會用getter去賦值屬性呢,但是這個作為一個簡單的case,甚至都算不上邊界,我們需要解決它。

    解決的方法也很簡單,就是通過Reflect。這也是為什么我說ProxyReflect就是焦不離孟 孟不離焦. 我們的reactive,get的時候,加入第三個參數(shù)receiver

    get(target,key){
        track(target,key,receiver)
        return Reflect.get(target,key,receiver)
    }

    我這里理解的是,receiver就相當(dāng)于函數(shù)的bind方法,它改變的this的執(zhí)行,當(dāng)我們同過Reflect讀取值的時候,this的指向被改為receiver,而Reflect時的receiver又是Proxy中的入?yún)?,它?zhí)行了這個Proxy,從而把前文中this的指向由obj改為data,這樣響應(yīng)式就不會丟失了。

    以上就是關(guān)于“vue3響應(yīng)式Proxy與Reflect如何使用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI