Vue不能觀察到數(shù)組length的變化
由于 JavaScript 的限制,Vue 不能檢測(cè)以下變動(dòng)的數(shù)組: 當(dāng)你利用索引直接設(shè)置一個(gè)項(xiàng)時(shí),例如:vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長(zhǎ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的時(shí)候只能遍歷出0, 1, 2,導(dǎo)致了只有前三個(gè)索引被加上了getter 和setter
var a = [0, 1, 2] a.length = 10 // 只是顯示的給length賦值,索引3-9的對(duì)應(yīng)的value也會(huì)賦值undefined // 但是索引3-9的key都是沒有值的 // 我們可以用for-in打印,只會(huì)打印0,1,2 for (var key in a) { console.log(key) // 0,1,2 }
那么vue提供了一些解決方法
使用內(nèi)置的Vue.$set
讓數(shù)組顯式的進(jìn)行某個(gè)索引的觀察 Vue.set(array, indexOfItem, newValue)
實(shí)際上是調(diào)用了
Object.defineProperty(array, indexOfItem, { enumerable: true, configurable: true, get() { }, set(newVal) { } })
這樣可以手動(dòng)指定需要觀察的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)行了方法重寫或者添加
并且對(duì)添加屬性的方法如 push,unshift,splice 所添加進(jìn)來的新屬性進(jìn)行手動(dòng)觀察,源碼為
if (inserted) ob.observeArray(inserted)
對(duì)以上方法進(jìn)行了手動(dòng)的進(jìn)行消息觸發(fā)
ob.dep.notify()
結(jié)論
vue對(duì)數(shù)組的length直接改變無法直接進(jìn)行觀察,提供了vue.$set 進(jìn)行顯式觀察,并且重寫了 push, pop, shift, unshift, splice, sort, reverse方法來進(jìn)行隱式觀察。
以上所述是小編給大家介紹的Vue不能觀察到數(shù)組length的變化,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
深入淺析Vue.js中 computed和methods不同機(jī)制
這篇文章給大家介紹了Vue.js中 computed和methods不同機(jī)制,在vue.js中,methods和computed兩種方式來動(dòng)態(tài)當(dāng)作方法使用,文中還給大家提到了computed和methods的區(qū)別,感興趣的朋友一起看看吧2018-03-03vue 項(xiàng)目@change多個(gè)參數(shù)傳值多個(gè)事件的操作
這篇文章主要介紹了vue 項(xiàng)目@change多個(gè)參數(shù)傳值多個(gè)事件的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01vue3解決各場(chǎng)景l(fā)oading過度的五種方法
這篇文章主要為大家詳細(xì)介紹了vue3中解決各場(chǎng)景l(fā)oading過度的五種方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下2023-11-11vue中選中多個(gè)選項(xiàng)并且改變選中的樣式的實(shí)例代碼
這篇文章主要介紹了vue中選中多個(gè)選項(xiàng)并且改變選中的樣式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Vue 3自定義指令開發(fā)的相關(guān)總結(jié)
這篇文章主要介紹了Vue 3自定義指令開發(fā)的相關(guān)總結(jié),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01vue子元素綁定的事件, 阻止觸發(fā)父級(jí)上的事件處理方式
這篇文章主要介紹了vue子元素綁定的事件, 阻止觸發(fā)父級(jí)上的事件處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11