title: Vue 更新data選項中的數(shù)組
date: 2018-12-18 18:05:19
tags: [Vue]
categories: Vue
疑問
最近看到一道面試題,如下:
var vm = new Vue({
data: {
items: [1, 2, 3]
}
})
vm.items[1] = 'x'
vm.items.length = 2
這樣寫有什么問題?那應該怎么寫?
我看到這道題時并不覺得有什么問題。在Vue中,一旦響應式數(shù)據(jù)發(fā)生改變,setter 不是會發(fā)通知給 watcher 嗎?
解答
后來我才知道,這樣子寫的話 Vue 不會更新該數(shù)組數(shù)據(jù)對應的視圖。
請先閱讀完官方文檔的 深入響應式原理,再看下面:
- 數(shù)據(jù)確實更新了,但視圖沒有更新,那就說明 Vue 并沒有檢測到該數(shù)據(jù)更新了
- 其實是數(shù)組的問題,在 Vue 中它比較特殊。
- 我們知道,Vue 會在初始化實例時對屬性執(zhí)行
getter/setter轉(zhuǎn)化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉(zhuǎn)換它,這樣才能讓數(shù)據(jù)是響應式的。 - 往深了說,其實 Vue 在我們的data對象上都會定義一個ob屬性指向新創(chuàng)建的Observer對象,以此對數(shù)據(jù)設置監(jiān)控器。但由于現(xiàn)代 JavaScript 的限制(底層原理不明),
Object.Observe支持的不好,Vue 無法對數(shù)組進行Observer對象創(chuàng)建,因此不能檢測到數(shù)組對象的變化。 - 不過 Vue 給我們提供了別的方法,具體見下面。
解決方法
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.items.splice(newLength)