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

首頁 > 編程 > JavaScript > 正文

Vue數(shù)據(jù)驅(qū)動模擬實現(xiàn)4

2019-11-19 17:58:58
字體:
供稿:網(wǎng)友

一、前言

在"模擬Vue之數(shù)據(jù)驅(qū)動3"中,我們實現(xiàn)了為每個對象擴展一個$set方法,用于新增屬性使用,這樣就可以監(jiān)聽新增的屬性了。

當然,數(shù)組也是對象,也可以通過$set方法實現(xiàn)新增屬性。

但是,對于數(shù)組而言,通常我們是通過push之類的方法吧。

PS:Vue中明確指出push、pop、shift、unshift、splice、sort、reverse方法為變異方法,可以通過它們監(jiān)聽屬性變化,觸發(fā)視圖更新(詳情見here

下面,我們就一起來實現(xiàn)這些Array的變異方法吧。

注:我們將Array變異方法實現(xiàn),也寫在extendObj.js中的,因為數(shù)組也是對象嘛。

二、Array變異方法實現(xiàn)

要實現(xiàn)這些變異方法,毫無疑問,我們會重寫它們,那在Array.prototype里面重寫嗎?

當然不是,這樣不就影響了所有數(shù)組對象的原型鏈了么!

為了避免這種情況,且,我們只是想在監(jiān)聽數(shù)據(jù)對象上繼承這些變異數(shù)組方法,那么細心的你會發(fā)現(xiàn),其實與我們在"模擬Vue之數(shù)據(jù)驅(qū)動3"中實現(xiàn)$set方法類似了。

首先,我們創(chuàng)建arrKeys對象用于保存需要變異的數(shù)組方法以及恒定對象extendArr,如下:

let arrKeys = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];const extendArr = [];

接著,就是在extendArr對象上,一一監(jiān)聽arrKeys中的方法了,與$set方法類似,整體結(jié)構(gòu)如下:

!function(){  arrKeys.forEach(function(key){    proxyObject(extendArr, key, function(){      //TODO    });  });}();

注:proxyObject方法其實核心就是Object.defineProperty,詳見"模擬Vue之數(shù)據(jù)驅(qū)動3".

接下來,就是實現(xiàn)核心部分代碼了,重寫這些方法的目的,是為了監(jiān)聽數(shù)據(jù)變化,所以要在方法原有功能不變的情況下,重寫它們,Array.xxx.apply即可實現(xiàn)原有功能。

且,push、unshift、splice這三個方法可以在原數(shù)組中,新增屬性,故而,我們需要監(jiān)聽新增屬性以及它們的屬性值,這里就和$set方法完全一樣了,通過$Observer,即可利用observe以及convert方法實現(xiàn)了。

實現(xiàn)代碼如下:

!function(){  arrKeys.forEach(function(key){    proxyObject(extendArr, key, function(){      console.log('Fun ' + key + ' is observed');      let result;      let arrProto = Array.prototype;      let ob = this.$Observer;      let arr = arrProto.slice.call(arguments);      let inserted;      let index;      switch(key){        case 'push': {          inserted = arr;          index = this.length;          break;        }        case 'unshift': {          inserted = arr;          index = 0;          break;        }        case 'splice': {          inserted = arr.slice(2);          index = arr[0];          break;        }      }      result = arrProto[key].apply(this, arguments);      if(inserted){        inserted.forEach(val => {          ob.observe(val);          ob.convert(index++, val);        });      }      return result;    });  });}();

最后,就是在需要監(jiān)聽的對象上繼承這些變異方法咯,如下:

//observer.jsfunction Observer(data){  if(!(this instanceof Observer)){    return new Observer(data);  }  data.__proto__ = extendObj;  //繼承變異方法push、pop等等  if(Array.isArray(data)){    data.__proto__.__proto__ = extendArr;  }  this.data = data;  this.walk(data);  }

好了,一切完畢,接下來就測試下唄:

<script src="./extendObj.js"></script><script src="./observer.js"></script><script>  'use strict';  let data = {    msg: [5, 2, 0],    user: {      name: 'Monkey',      age: 24    },    lover: {      name: 'Dorie',      age: 23    }  };  Observer(data);</script>

效果如下:

Perfect,此時,你可能會想,數(shù)組方法中僅有push、unshift、splice會為數(shù)組新增屬性,那么我們又何必將其他方法,例如sort、reverse重寫呢,也沒發(fā)現(xiàn)有什么貓膩呢?

不錯,在此時,并沒有什么卵用,但是,你要知道sort、reverse等這些方法,可是會引起數(shù)組變化的,那么就會影響視圖展現(xiàn),這些變化,又怎么通知數(shù)組呢?就是下篇隨筆會具體說明的。

該篇隨筆代碼,詳情見github.

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 简阳市| 北辰区| 常熟市| 庆阳市| 武陟县| 陆河县| 宝坻区| 卢湾区| 沙湾县| 元氏县| 天台县| 黄梅县| 咸宁市| 比如县| 县级市| 台南市| 五指山市| 罗源县| 大港区| 广昌县| 蒲城县| 六枝特区| 滦平县| 五河县| 河源市| 新密市| 凤阳县| 邵阳县| 兴文县| 资源县| 盐津县| 莱州市| 砀山县| 滨州市| 大冶市| 澄城县| 南郑县| 连平县| 开平市| 兴安县| 扶沟县|