您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Vue模擬實現數據驅動的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Vue模擬實現數據驅動的示例分析”這篇文章吧。
一、前言
之前實現了為每個對象擴展一個$set方法,用于新增屬性使用,這樣就可以監聽新增的屬性了。
當然,數組也是對象,也可以通過$set方法實現新增屬性。
但是,對于數組而言,通常我們是通過push之類的方法吧。
PS:Vue中明確指出push、pop、shift、unshift、splice、sort、reverse方法為變異方法,可以通過它們監聽屬性變化,觸發視圖更新(詳情見here)
下面,我們就一起來實現這些Array的變異方法吧。
注:我們將Array變異方法實現,也寫在extendObj.js中的,因為數組也是對象嘛。
二、Array變異方法實現
要實現這些變異方法,毫無疑問,我們會重寫它們,那在Array.prototype里面重寫嗎?
當然不是,這樣不就影響了所有數組對象的原型鏈了么!
為了避免這種情況,且,我們只是想在監聽數據對象上繼承這些變異數組方法,那么細心的你會發現,其實與我們在"模擬Vue之數據驅動3"中實現$set方法類似了。
首先,我們創建arrKeys對象用于保存需要變異的數組方法以及恒定對象extendArr,如下:
let arrKeys = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']; const extendArr = [];
接著,就是在extendArr對象上,一一監聽arrKeys中的方法了,與$set方法類似,整體結構如下:
!function(){ arrKeys.forEach(function(key){ proxyObject(extendArr, key, function(){ //TODO }); }); }();
注:proxyObject方法其實核心就是Object.defineProperty,詳見"模擬Vue之數據驅動3".
接下來,就是實現核心部分代碼了,重寫這些方法的目的,是為了監聽數據變化,所以要在方法原有功能不變的情況下,重寫它們,Array.xxx.apply即可實現原有功能。
且,push、unshift、splice這三個方法可以在原數組中,新增屬性,故而,我們需要監聽新增屬性以及它們的屬性值,這里就和$set方法完全一樣了,通過$Observer,即可利用observe以及convert方法實現了。
實現代碼如下:
!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; }); }); }();
最后,就是在需要監聽的對象上繼承這些變異方法咯,如下:
//observer.js function 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>
效果如下:
以上是“Vue模擬實現數據驅動的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。