国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Vue數據驅動模擬實現5

2019-11-19 17:57:40
字體:
來源:轉載
供稿:網友

一、前言

在"模擬Vue之數據驅動4"中,我們實現了push、pop等數組變異方法。

但是,在隨筆末尾我們提到,當pop、sort這些方法觸發后,該怎么辦呢?因為其實,它們并沒有往數組中新增屬性呢。

而且,當數據改動后,如果我們在變動數據處,就立即更改數據也未免性能不夠,此時,走讀Vue源碼,發現他用了一個很巧妙的方法,就是職責鏈模式。當某個數據有所變動時,它會向上傳遞,通俗點就是冒泡至根結點,這樣我們也可以在自己代碼中使用事件代理咯,哇卡哇卡。

示意圖如下所示:

好了,說了這么多,我們下面就一起來實現下吧。

二、正文

注:以下代碼皆編寫在observer.js文件中。

首先,當數據變動,或者觸發某個事件時,我們需要與變動數據關聯一個自定義事件(自定義事件詳情見here),如果觸發某個事件,那么就執行,如下:

綁定事件方法:

//let p = Observer.prototypep.on = function(eventName, fn){ let listener = this.listener = this.listener || []; if(typeof eventName === 'string' && typeof fn === 'function'){  if(!listener[eventName]){   listener[eventName] = [fn];  }else{   listener[eventName].push(fn);  } } }

取消事件方法:

//let p = Observer.prototypep.off = function(eventName, fn){ let listener = this.listener = this.listener || []; let actionArray = listener[eventName]; if(typeof eventName === 'string' && Array.isArray(actionArray)){  if(typeof fn === 'function'){   actionArray.forEach( (func, i, arr) => {    if(func === fn){     arr.splice(i,1);     }   });  } }}

觸發事件方法:

//let p = Observer.prototypep.emit = function(eventName){ let listener = this.listener = this.listener || []; let actionArray = listener[eventName]; if(Array.isArray(actionArray)){  actionArray.forEach( func => {   if(typeof func === 'function'){    func();    }  });  }}

其次,就是當數據變動,觸發自身相關事件后,怎么一路冒泡到根結點的處理了。

怎么冒泡到根結點呢?

那就自身結點關聯父結點嘛,這樣不就可以追溯到根節點了么。

所以,我們在Observer.walk時,就將自己的父節點記錄即可,如下:

//let p = Observer.prototypep.observe = function(key, data){ if(typeof data === 'object'){  let ob = new Observer(data);   //關聯父節點  ob._parent = {   key,   ob: this  }; } }

最后,有了子父結點的依賴關系,那么冒泡方法就OK啦,如下:

//let p = Observer.prototypep.notify = function(eventName){ let ob = this._parent && this._parent.ob; let key = ob && this._parent.key || 'root'; console.log('parent--'+key+' event--'+eventName); this.emit(eventName); //判斷節點是否有父節點,若有,就向上傳遞事件 ob && ob.notify(eventName); }

Perfect,具體代碼詳見github.

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 台中市| 滦平县| 祁连县| 青阳县| 中西区| 哈尔滨市| 弥渡县| 台北县| 博湖县| 咸阳市| 正阳县| 长岭县| 三原县| 长子县| 景泰县| 伊宁县| 丹阳市| 尼木县| 万载县| 澄江县| 闸北区| 株洲市| 哈密市| 中阳县| 绥宁县| 重庆市| 龙陵县| 嘉鱼县| 蕉岭县| 武山县| 乃东县| 象州县| 衡阳县| 开原市| 沽源县| 长宁县| 宁武县| 来宾市| 温泉县| 阜城县| 莱芜市|