title: Vue 更新data選項中的數組
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中,一旦響應式數據發生改變,setter 不是會發通知給 watcher 嗎?
解答
后來我才知道,這樣子寫的話 Vue 不會更新該數組數據對應的視圖。
請先閱讀完官方文檔的 深入響應式原理,再看下面:
- 數據確實更新了,但視圖沒有更新,那就說明 Vue 并沒有檢測到該數據更新了
- 其實是數組的問題,在 Vue 中它比較特殊。
- 我們知道,Vue 會在初始化實例時對屬性執行
getter/setter
轉化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓數據是響應式的。 - 往深了說,其實 Vue 在我們的data對象上都會定義一個ob屬性指向新創建的Observer對象,以此對數據設置監控器。但由于現代 JavaScript 的限制(底層原理不明),
Object.Observe
支持的不好,Vue 無法對數組進行Observer對象創建,因此不能檢測到數組對象的變化。 - 不過 Vue 給我們提供了別的方法,具體見下面。
解決方法
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.items.splice(newLength)