您好,登錄后才能下訂單哦!
這篇“vue3響應式Proxy與Reflect如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue3響應式Proxy與Reflect如何使用”文章吧。
vue3的響應式離不開Proxy
,說到Proxy
則離不開Reflect
.這兩個對象是ES6新增的對象,同時在編程領域,他們也代表著2種設計模式,即代理與反射。
Proxy
可以理解成,在目標對象之前架設一層“攔截”,外界對該對象的訪問,都必須經過這層攔截,而我們就可以通過這層攔截去改變目標對象的內容或者行為,或者叫過濾和控制。這個詞本意就是代理,好比一個代理人站在神奇,我們所有行為都會被他過濾,可能我們說的話,經過代理人一說,意思就變了。
ES6 原生提供 Proxy 構造函數,用來生成 Proxy 實例。
var proxy = new Proxy(target, handler);
其中target
表示要代理的那個對象,handler
則是表示我們需要攔截的行為,這里直接放一張阮一峰的截圖。
Reflect
中文譯為:反射。如果說Proxy
是有一個代理人站在身前面,幫你攔截并處理一些行為,那么Reflect
就是你身后的一面鏡子,它能看見真實的自己。
而你自己,就是一個類或者對象,或者一個函數,只要是js中存在的,都能被Proxy
和 Reflect
處理。
它的操作和Proxy
正好相反,但卻一一對應。比如我們獲取對象中一個屬性。
const obj = {foo:1} const a = Reflect.get(obj, 'foo')
這一小節主要是介紹了Proxy與Reflect,后面會有一個應用老告訴你為什么Proxy與Reflect與響應式數據息息相關。
看完了Proxy
與Reflect
的基本使用之后,我們實踐一下。
我們曾經寫過這樣的代碼
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
代理了對象讀和取操作,在讀的時候收集依賴,在取的時候觸發響應。看起來似乎沒有問題,那么我們再試繼續往下寫
const obj = { a:1, get b(){ return this.a } } const data = reactive(obj) effect(()=>{ console.log(data.b) }) setTimeOut(()=>{ data.b++ },500)
這里我們沒有用一般的對象寫法,而是通過訪問器為它新增了一個b屬性.之后,我們先把這個對象轉換為響應式對象,再給他們設定一個響應式的回調,然后在冬天改變他的值,理論上這時候應該會執行副作用函數,但是實際上呢,根本不會執行。
我們回顧一下之前寫的reactive
方法,在里面返回的是target[key]
,當我們的target是obj,key是b的時候,那個this會是誰呢?因為target是原始對象,也就是obj,根據誰調用是誰的原則,這個this也就指向了obj。obj是響應式對象嗎,顯然不是,那個b也就永遠不會執行副作用函數,響應式就失效了。
這里其實就是this的指向問題,你可能會說一般人怎么會用getter去賦值屬性呢,但是這個作為一個簡單的case,甚至都算不上邊界,我們需要解決它。
解決的方法也很簡單,就是通過Reflect
。這也是為什么我說Proxy
與Reflect
就是焦不離孟 孟不離焦. 我們的reactive,get的時候,加入第三個參數receiver
get(target,key){ track(target,key,receiver) return Reflect.get(target,key,receiver) }
我這里理解的是,receiver
就相當于函數的bind
方法,它改變的this的執行,當我們同過Reflect
讀取值的時候,this的指向被改為receiver
,而Reflect
時的receiver
又是Proxy
中的入參,它執行了這個Proxy
,從而把前文中this的指向由obj改為data,這樣響應式就不會丟失了。
以上就是關于“vue3響應式Proxy與Reflect如何使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。