亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁技術文章
文章詳情頁

Vue Object 的變化偵測實現代碼

瀏覽:33日期:2023-01-26 17:31:59

數據觀察

Vue 中的對象變化偵測是通過Object.definePorperty實現的,但是Object.definePorperty的方式有缺陷,比如不能直接代理整個對象,每次都要循環遍歷對象的所有屬性;尤大大說之后會使用 ES6 中的Proxy 重寫這個部分。這篇博客介紹的是 Object.definePorperty 實現的對象偵測。

我們來看下面這段代碼,定義一個 defineReactive 函數,使用 Object.definePorperty 遍歷對象對象屬性的時候,設置 get 和 set;當對象屬性被讀取的時候觸發 get,對象屬性被設置的時候觸發 set。這樣就完成了對 data 的數據劫持,因為 Vue 的思想是響應式的,我們還需要收集這些變化。

function defineReactive(data,key,val){ Object.definePorperty(data,key,{ enumerable: true, configurable: true, get:function(){ return val; } set :function (newVal){ if(val === newVal){return} val = newVal; } })}

依賴 收集

創建一個 Dep 類,在 get 中收集依賴,在 set 中新增依賴

class Dep{ constructor(){ this.arr = [] } addSub(sub){ this.arr.push(sub) } removeSub(sub){ remove(this.arr,sub) } depend(){ if(window.target){ this.addSub(window.target) } } notify(){ const arrs = this.arr.slice(); for(let i = 0; i< arrs.lenth ;i ++){ arrs[i].update(); } }}function defineReactive(data,key,val){ let dep = new Dep() Object.definePorperty(data,key,{ enumerable: true, configurable: true, get:function(){ dep.depend(); // 收集依賴 return val; } set :function (newVal){ if(val === newVal){return} val = newVal; dep.notify(); // 新增依賴 } })}

Observer 和 Watcher

我們發現 defineReactive 函數只能將某一個屬性轉換為 get/set 的形式,所以我們需要一個觀察者 Observer 用來幫助遞歸的偵測所有的 key

class Observer{ constructor(value){ this.value = value } if(!Array.isArry(value)){ this.walk(value) } walk(obj){ const keys = Object.keys(obj) for(let i = 0; i < keys.length ;i++){ defineReactive(data,keys[i],obj[keys[i]) } }}

當這些依賴收集完成之后,我們要通知誰呢?怎么樣能讓視圖知道有變化更新?我們需要實現一個訂閱者 Watcher,每次觸發 get 的時候都將 dep 指向自己,這樣就可以收集到依賴;每次 set 的時候都循環調用 Watcher 的 update 方法。

class Watcher{ constructor(vm,exp,cb){ this.vm = vm; this.cb = cb; this.exp = exp; this.value = this.get(); } get(){ Dep.target = this; // 將當前訂閱者指向自己 var value = this.vm[exp]; // 觸發getter,添加自己到屬性訂閱器中 Dep.target = null; // 添加完畢,重置 return value; } update(){ const oldVal = this.value; this.value = this.get(); this.cb.call(this.vm,this.value,oldVal) }}

當 Vue 實例掛載好之后,模板都會綁定一個 Watcher,誰的屬性發生變化了就會通知響應的 Watcher,Watcher 再去通知編譯器 Compile 進行視圖更新

偵測沒辦法監聽到對象上屬性的新增和刪除

Vue 通過Object.definePorperty將對象的 key 轉化為 getter setter 的形式來進行偵測,但是無法追蹤到屬性的新增和刪除,所以 Vue 中提供了 vm.get 來實現

到此這篇關于Vue Object 的變化偵測實現代碼的文章就介紹到這了,更多相關Vue Object 變化偵測 內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
主站蜘蛛池模板: 亚洲国产高清在线精品一区 | 成人高清视频在线观看 | 免费一区二区三区视频狠狠 | 成人国产精品高清在线观看 | 中文字幕一区二区三区亚洲精品 | 成人午夜免费视频 | 成人自拍视频 | 91视频国产精品 | 在线视频一区二区日韩国产 | 国产国语对白一级毛片 | 欧美国产综合视频 | 成人高清视频在线观看 | 男人操美女逼视频 | 三级网站免费看 | 国产高清a毛片在线看 | 日韩毛片欧美一级a网站 | h亚洲 | 91精品网站 | 精品欧美高清一区二区免费 | 宫女淫春3在线观 | 国产精品久久一区一区 | 91老色批网站免费看 | 午夜不卡视频 | 国产亚洲一区二区手机在线观看 | 亚洲成年人专区 | 精品久久网 | 正在播放国产精品放孕妇 | 成人三级在线视频 | 欧美精品黄页免费高清在线 | 97在线视频网站 | 免费国产成人α片 | 国产成人三级经典中文 | 亚洲美女在线观看亚洲美女 | 国内亚州视频在线观看 | 日韩美女网站在线看 | 国产国产人免费人成成免视频 | 高清一区二区在线观看 | 欧美xxxxx毛片 | 真人一级毛片免费观看视频 | 午夜视频在线观看一区二区 | 亚洲欧美国产精品专区久久 |