Vue不能觀察到數(shù)組length的變化
由于 JavaScript 的限制,Vue 不能檢測以下變動的數(shù)組: 當(dāng)你利用索引直接設(shè)置一個項時,例如:vm.items[indexOfItem] = newValue 當(dāng)你修改數(shù)組的長度時,例如:vm.items.length = newLength
因?yàn)関ue的響應(yīng)式是通過 Object.defineProperty 來實(shí)現(xiàn)的,但是數(shù)組的length屬性是不能添加getter和setter,所有無法通過觀察length來判斷。
為什么Vue不能觀察到數(shù)組length的變化
如下代碼,雖然看起來數(shù)組的length是10,但是for in的時候只能遍歷出0, 1, 2,導(dǎo)致了只有前三個索引被加上了getter 和setter
var a = [0, 1, 2]
a.length = 10
// 只是顯示的給length賦值,索引3-9的對應(yīng)的value也會賦值undefined
// 但是索引3-9的key都是沒有值的
// 我們可以用for-in打印,只會打印0,1,2
for (var key in a) {
console.log(key) // 0,1,2
}
那么vue提供了一些解決方法
使用內(nèi)置的Vue.$set
讓數(shù)組顯式的進(jìn)行某個索引的觀察 Vue.set(array, indexOfItem, newValue)
實(shí)際上是調(diào)用了
Object.defineProperty(array, indexOfItem, {
enumerable: true,
configurable: true,
get() { },
set(newVal) { }
})
這樣可以手動指定需要觀察的key,那么就可以達(dá)到預(yù)期的效果。
重寫了 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__上 進(jìn)行了方法重寫或者添加
并且對添加屬性的方法如 push,unshift,splice 所添加進(jìn)來的新屬性進(jìn)行手動觀察,源碼為
if (inserted) ob.observeArray(inserted)
對以上方法進(jìn)行了手動的進(jìn)行消息觸發(fā)
ob.dep.notify()
結(jié)論
vue對數(shù)組的length直接改變無法直接進(jìn)行觀察,提供了vue.$set 進(jìn)行顯式觀察,并且重寫了 push, pop, shift, unshift, splice, sort, reverse方法來進(jìn)行隱式觀察。
以上所述是小編給大家介紹的Vue不能觀察到數(shù)組length的變化,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Vue3封裝全局Dialog組件的實(shí)現(xiàn)方法
3封裝全局Dialog組件相信大家都不陌生,下面這篇文章主要給大家介紹了關(guān)于Vue3封裝全局Dialog組件的實(shí)現(xiàn)方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
vue自定義底部導(dǎo)航欄Tabbar的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue自定義底部導(dǎo)航欄Tabbar的實(shí)現(xiàn)代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09
Vue中渲染系統(tǒng)模塊的實(shí)現(xiàn)詳解
想要實(shí)現(xiàn)一個簡潔版的Mini-Vue框架,應(yīng)該包含三個模塊:分別是:渲染系統(tǒng)模塊、可響應(yīng)式系統(tǒng)模塊、應(yīng)用程序入庫模塊,本文主要介紹的是渲染系統(tǒng)模塊的實(shí)現(xiàn),需要的可以參考一下2023-07-07
ant design vue動態(tài)循環(huán)生成表單以及自定義校驗(yàn)規(guī)則詳解
這篇文章主要介紹了ant design vue動態(tài)循環(huán)生成表單以及自定義校驗(yàn)規(guī)則詳解,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01

