您现在的位置是:Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款 >
02 vue發布訂閱模式原理(理解VUE2雙向數據綁定原理和實現)
Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款2024-06-17 17:21:45【】6人已围观
简介ue3采用了新的Proxy實現數據讀取和設置攔截,不僅彌補了之前Vue2中Object.defineProperty的缺陷,同時也帶來了性能上的提升。今天,我們就來盤一盤它,看看Vue3中響應式是如何
今天,我們就來盤一盤它,看看 Vue3 中響應式是如何實現的。
The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object. MDN
Proxy - 代理,顧名思義,就是在要訪問的對象之前增加一個中間層,這樣就不直接訪問對象,而是通過中間層做一個中轉,通過操作代理對象,來實現修改目標對象。
Vue3 中響應式核心方法就是 reactive 和 effect , 其中 reactive 方法是負責將數據變成響應式, effect 方法的作用是根據數據變化去更新視圖或調用函數,與 react 中的 useEffect 有點類似~
其大概用法如下:
默認會執行一次,打印 Hello , 之后更改了 data.name 的值后,會在觸發執行一次,打印 World 。
我們先看看 reactive 方法的實現~
reactive.js
首先應該明確,我們應該導出一個 reactive 方法,該方法有一個參數 target ,目的就是將 target 變成響應式對象,因此返回值就是一個響應式對象。
reactive 方法基本結構就是如此,給定一個對象,返回一個響應式對象。
其中 isObject 方法用于判斷是否是對象,不是對象不需要代理,直接返回即可。
reactive 方法的重點是 Proxy 的第二個參數 handler ,它承載監控對象變化,依賴收集,視圖更新等各項重大責任,我們重點來研究這個對象。
handler.js
在 Vue3 中 Proxy 的 handler 主要設置了 get , set , deleteProperty , has , ownKeys 這些屬性,即攔截了對象的讀取,設置,刪除, in 以及 Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法。
這里我們偷個懶,暫時就考慮 set 和 get 操作。
handler.get()
get 獲取屬性比較簡單,我們先來看看這個,這里我們用一個方法創建 getHanlder 。
這里推薦使用了 Reflect.get 而并非 target[key] 。
可以發現, Vue3 是在取值的時候才去遞歸遍歷屬性的,而非 Vue2 中一開始就遞歸 data 給每個屬性添加 Watcher ,這也是 Vue3 性能提升之一。
handler.set()
同理 set 操作,我們也是用一個方法創建 setHandler 。
Reflect.set 會返回一個 Boolean 值,用于判斷屬性是否設置成功。
完事后將 handler 導出,然后在 reactive 中引入即可。
測試幾組對象貌似沒啥問題,其實是有一個坑,這個坑也跟數組有關。
如上例子,如果我們選擇代理數組,在 setHandler 中打印其 key 和 value 的話會得到 3 4 , length 4 這兩組值:
如果不作處理,那么會導致如果更新視圖的話,則會觸發兩次,這肯定是不允許的,因此,我們需要將區分新增和修改這兩種操作。
Vue3 中是通過判斷 target 是否存在該屬性來區分是新增還是修改操作,需要借助一個工具方法 —— hasOwnProperty 。
這里我們將上述的 createSetter 方法修改如下:
如此一來,我們調 push 方法的時候,就只會觸發一次更新了,非常巧妙的避免了無意義的更新操作。
effect.js
光上述構造響應式對象并不能完成響應式的操作,我們還需要一個非常重要的方法 effect ,它會在初始化執行的時候存儲跟其有關的數據依賴,當依賴數據發生變化的時候,則會再次觸發 effect 傳遞的函數。
其基本雛形如下,入參是一個函數,還有個可選參數 options 方便后面計算屬性等使用,暫時不考慮:
createReactiveEffect 就是為了將 fn 變成響應式函數,監控數據變化,執行 fn 函數,因此該函數是一個高階函數。
createReactiveEffect 將原來的 fn 轉變成一個 reactvieEffect , 并將當前的 effect 掛到全局的 activeEffect 上,目的是為了一會與當前所依賴的屬性做好對應關系。
我們必須要將依賴屬性構造成 { prop : [effect,effect] } 這種結構,才能保證依賴屬性變化的時候,依次去觸發與之相關的 effect ,因此,需要在 get 屬性的時候,做屬性的依賴收集,將屬性與 effect 關聯起來。
依賴收集 —— track
在獲取對象的屬性時,會觸發 getHandler ,再次做屬性的依賴收集,即 Vue2 中的發布訂閱。
在 setHandler 中獲取屬性的時候,做一次 track(target, key) 操作。
整個 track 的數據結構大概是這樣
目的就是將 target , key , effect 之間做好對應的關系映射。
打印 targetMap 的結構如下:
**觸發更新 —— trigger
**上述已經完成了依賴收集,剩下就是監控數據變化,觸發更新操作,即在 setHandler 中添加 trigger 觸發操作。
這樣一來,獲取數據的時候通過 track 進行依賴收集,更新數據的時候再通過 trigger 進行更新,就完成了整個數據的響應式操作。
再回頭看看我們先前提到的例子:
控制臺會依次打印 Hello ***** effect ***** 以及 World ***** effect ***** , 分別是首次渲染觸發跟更新數據重渲染觸發,至此功能實現!
整體來說, Vue3 相比于 Vue2 在很多方面都做了調整,數據的響應式只是冰山一角,但是可以看出尤大團隊非常巧妙的利用了 Proxy 的特點以及 es6 的數據結構和方法。另外, Composition API 的模式跟 React 在某些程度上有異曲同工之妙,這種設計模式讓我們在實際開發使用中更加的方法快捷,值得我們去學習,加油!
最后附上倉庫地址 github ,歡迎各位大佬批評斧正~
Vue的雙向數據綁定原理
Vue 數據雙向綁定主要是指:數據變化更新視圖,視圖變化更新數據
實現原理:采用數據監聽、解析結合訂閱者模式的方式,通過Object.defineProperty()來監聽各個屬性的setter,getter,在數據變動時發布消息給訂閱者,觸發相應的監聽回調。從而實現數據的雙向綁定
Vue 主要通過以下 4 個步驟來實現數據雙向綁定的:
1、實現一個監聽器 Observer:對數據對象進行遍歷,包括子屬性對象的屬性,利用 Object.defineProperty() 對屬性都加上 setter 和 getter。這樣的話,給這個對象的某個值賦值,就會觸發 setter,那么就能監聽到了數據變化。
2、實現一個解析器 Compile:解析 Vue 模板指令,將模板中的變量都替換成數據,然后初始化渲染頁面視圖,并將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,調用更新函數進行數據更新。
3、實現一個訂閱者 Watcher:Watcher 訂閱者是 Observer 和 Compile 之間通信的橋梁 ,主要的任務是訂閱 Observer 中的屬性值變化的消息,當收到屬性值變化的消息時,觸發解析器 Compile 中對應的更新函數。
4、實現一個訂閱器 Dep:訂閱器采用 發布-訂閱 設計模式,用來收集訂閱者 Watcher,對監聽器 Observer 和 訂閱者 Watcher 進行統一管理。
vue是怎么將數據綁定到組件的原理
vue將數據綁定到組件的原理如下:
1、當實例化一個Vue構造函數,會執行 Vue 的 init 方法,在 init 方法中主要執行三部分內容,一是初始化環境變量,而是處理 Vue 組件數據,三是解析掛載組件。以上三部分內容構成了 Vue 的整個執行過程。
2、Vue 實現了一個 觀察者-消費者(訂閱者) 模式來實現數據驅動視圖。通過設定對象屬性的 setter/getter 方法來監聽數據的變化,而每個屬性的 setter 方法就是一個觀察者, 當屬性變化將會向訂閱者發送消息,從而驅動視圖更新。
3、Vue 的訂閱者 watcher 實現在 /src/watchr.js 。構建一個 watcher 最重要的是 expOrFn 和 cb 兩個參數,cb 是訂閱者收到消息后需要執行的回調,一般來說這個回調都是視圖指令的更新方法,從而達到視圖的更新,但是這也不是必須的,訂閱回調也可以是一個和任何無關的純函數。一個訂閱者最重要的是要知道自己訂閱了什么,watcher 分析 expOrFn 的 getter 方法,從而間接獲得訂閱的對象屬性。
4、Vue 雙向數據綁定實現
數據與視圖的綁定與同步,最終體現在對數據的讀寫處理過程中,也就是 Object.defineProperty() 定義的數據 set、get 函數中。Vue 中對于的函數為 defineReactive,在精簡版實現中,我只保留了一些基本特性:
function defineReactive(obj, key, value)
很赞哦!(41)
相关文章
- 05 youtube on youtube music love songs歌詞(找一首英文歌的歌名)
- 06 廣西華翔貿易有限公司怎么樣(中國鑄造產品的在國際上的競爭力怎么樣,,,最好有數據比較。。急!!!!)
- 06 廣州華遠食品貿易有限公司(【精益生產管理專家】-安岷老師簡介)
- 05 youtube to mp3 download 買粉絲 download中文(小學英語語法歸納及語音訓練要視頻下載的誰有?)
- 05 youtube music u2 live(有人知道link park的一首老歌嗎?歌詞里面有一段復歌(是一段rap),有music ,moment等單詞的。)
- 06 廣州配得快汽配貿易有限公司(小車配件汽配城)
- 05 youtube to mp3 download mp3(高分懸賞!求一首英文流行歌曲)
- 06 廣州大清果貿易有限公司(黎婉華:一生榮華富貴,兒女卻死的死瘋的瘋,她的后半生真凄慘)
- 05 youtube to mp3 download 買粉絲 download for windows(P2P是什么意思??)
- 05 youtube to mp3 320kbps youtube music下載歌曲(如何在youtubemusic中創建快捷指令)
热门文章
站长推荐
05 youtube to mp3 買粉絲 app download 買粉絲 28(drm是什么意思 drm的中文翻譯、讀音、例句?)
05 youtube to mp3 app download 買粉絲(好聽的英文歌)
06 廣州歐墾進出口貿易有限公司(中國有幾大航空公司)
05 youtube music share playlist(如何在youtubemusic中創建快捷指令)
06 廣州壹甲社貿易有限公司(招標信息在哪查看?)
06 廣州達芊貿易有限公司(天際100觀景臺 天際100香港觀景臺多高)
06 廣州蔓川星貿易有限公司怎么樣(想開艾灸養生館取什么樣的名字好聽)
05 youtube music 買粉絲s music 買粉絲s 2015(今日新聞淺談:Youtube Music 也加入串流音樂服務大混戰)