国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Vue Object 的變化偵測(cè)實(shí)現(xiàn)代碼

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

數(shù)據(jù)觀察

Vue 中的對(duì)象變化偵測(cè)是通過(guò)Object.definePorperty實(shí)現(xiàn)的,但是Object.definePorperty的方式有缺陷,比如不能直接代理整個(gè)對(duì)象,每次都要循環(huán)遍歷對(duì)象的所有屬性;尤大大說(shuō)之后會(huì)使用 ES6 中的Proxy 重寫這個(gè)部分。這篇博客介紹的是 Object.definePorperty 實(shí)現(xiàn)的對(duì)象偵測(cè)。

我們來(lái)看下面這段代碼,定義一個(gè) defineReactive 函數(shù),使用 Object.definePorperty 遍歷對(duì)象對(duì)象屬性的時(shí)候,設(shè)置 get 和 set;當(dāng)對(duì)象屬性被讀取的時(shí)候觸發(fā) get,對(duì)象屬性被設(shè)置的時(shí)候觸發(fā) set。這樣就完成了對(duì) data 的數(shù)據(jù)劫持,因?yàn)?Vue 的思想是響應(yīng)式的,我們還需要收集這些變化。

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; } })}

依賴 收集

創(chuàng)建一個(gè) 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

我們發(fā)現(xiàn) defineReactive 函數(shù)只能將某一個(gè)屬性轉(zhuǎn)換為 get/set 的形式,所以我們需要一個(gè)觀察者 Observer 用來(lái)幫助遞歸的偵測(cè)所有的 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]) } }}

當(dāng)這些依賴收集完成之后,我們要通知誰(shuí)呢?怎么樣能讓視圖知道有變化更新?我們需要實(shí)現(xiàn)一個(gè)訂閱者 Watcher,每次觸發(fā) get 的時(shí)候都將 dep 指向自己,這樣就可以收集到依賴;每次 set 的時(shí)候都循環(huán)調(diào)用 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; // 將當(dāng)前訂閱者指向自己 var value = this.vm[exp]; // 觸發(fā)getter,添加自己到屬性訂閱器中 Dep.target = null; // 添加完畢,重置 return value; } update(){ const oldVal = this.value; this.value = this.get(); this.cb.call(this.vm,this.value,oldVal) }}

當(dāng) Vue 實(shí)例掛載好之后,模板都會(huì)綁定一個(gè) Watcher,誰(shuí)的屬性發(fā)生變化了就會(huì)通知響應(yīng)的 Watcher,Watcher 再去通知編譯器 Compile 進(jìn)行視圖更新

偵測(cè)沒(méi)辦法監(jiān)聽到對(duì)象上屬性的新增和刪除

Vue 通過(guò)Object.definePorperty將對(duì)象的 key 轉(zhuǎn)化為 getter setter 的形式來(lái)進(jìn)行偵測(cè),但是無(wú)法追蹤到屬性的新增和刪除,所以 Vue 中提供了 vm.get 來(lái)實(shí)現(xiàn)

到此這篇關(guān)于Vue Object 的變化偵測(cè)實(shí)現(xiàn)代碼的文章就介紹到這了,更多相關(guān)Vue Object 變化偵測(cè) 內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Vue
相關(guān)文章:
主站蜘蛛池模板: 日韩欧美国产另类 | 国产成人手机视频 | 欧美人成人亚洲专区中文字幕 | 日韩欧美在线一区二区三区 | 欧美精品片在线观看网站 | 五月久久噜噜噜色影 | 黄视频免费在线 | 欧美黄色精品 | 综合精品 | 久草在线播放视频 | 欧美日比视频 | 欧美成人性色生活片天天看 | 亚洲三级视频在线观看 | 狠狠色狠狠色综合 | 孕妇交 | 手机看片1024久久精品你懂的 | 日本韩国一区 | 毛片在线全部免费观看 | 小泽玛利亚的一级毛片的 | 久久久久亚洲精品一区二区三区 | 国产妇乱子伦视频免费 | 午夜视频久久 | 美女黄频免费看 | 一级黄色α片 | 欧美久久久久久久一区二区三区 | 亚洲乱码一区二区三区国产精品 | 免费看片aⅴ免费大片 | 久久性感视频 | 国产三级做爰在线观看视频 | 91久国产在线观看 | 99久久综合给久久精品 | 草草视频手机在线观看视频 | 色盈盈影院 | 亚洲欧洲日产国码一级毛片 | 亚洲男人的天堂久久香蕉 | 免费福利入口在线观看 | 成年人网站免费看 | 日本加勒比视频在线观看 | 国产成人免费影片在线观看 | 久久精品综合 | 99精品在线免费观看 |