由于 JavaScript 的限制,Vue 不能檢測以下變動的數組: 當你利用索引直接設置一個項時,例如:vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如:vm.items.length = newLength
因為vue的響應式是通過 Object.defineProperty 來實現的,但是數組的length屬性是不能添加getter和setter,所有無法通過觀察length來判斷。
為什么Vue不能觀察到數組length的變化
如下代碼,雖然看起來數組的length是10,但是for in的時候只能遍歷出0, 1, 2,導致了只有前三個索引被加上了getter 和setter
var a = [0, 1, 2] a.length = 10 // 只是顯示的給length賦值,索引3-9的對應的value也會賦值undefined // 但是索引3-9的key都是沒有值的 // 我們可以用for-in打印,只會打印0,1,2 for (var key in a) { console.log(key) // 0,1,2 }
那么vue提供了一些解決方法
使用內置的Vue.$set
讓數組顯式的進行某個索引的觀察 Vue.set(array, indexOfItem, newValue)
實際上是調用了
Object.defineProperty(array, indexOfItem, { enumerable: true, configurable: true, get() { }, set(newVal) { } })
這樣可以手動指定需要觀察的key,那么就可以達到預期的效果。
重寫了 push, pop, shift, unshift, splice, sort, reverse方法
Vue源碼
const arrayProto = Array.prototype export const arrayMethods = Object.create(arrayProto) /** * Intercept mutating methods and emit events */ ;[ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ] .forEach(function (method) { // cache original method const original = arrayProto[method] def(arrayMethods, method, function mutator (...args) { const result = original.apply(this, args) const ob = this.__ob__ let inserted switch (method) { case 'push': case 'unshift': inserted = args break case 'splice': inserted = args.slice(2) break } if (inserted) ob.observeArray(inserted) // notify change ob.dep.notify() return result }) })
這些是在Array.__proto__上 進行了方法重寫或者添加
并且對添加屬性的方法如 push,unshift,splice 所添加進來的新屬性進行手動觀察,源碼為
if (inserted) ob.observeArray(inserted)
對以上方法進行了手動的進行消息觸發
ob.dep.notify()
結論
vue對數組的length直接改變無法直接進行觀察,提供了vue.$set 進行顯式觀察,并且重寫了 push, pop, shift, unshift, splice, sort, reverse方法來進行隱式觀察。
以上所述是小編給大家介紹的Vue不能觀察到數組length的變化,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com