注意:
在一個組件實例中,只有在data里初始化的數據才是響應的,Vue不能檢測到對象屬性的添加或刪除,沒有在data里聲明的屬性不是響應的。
Vue不允許在已經創建的實例上動態添加根級響應式屬性,但是可以使用$set方法將相應屬性添加到嵌套的對象上。
數組數據變動,使用某些方法操作數組,變動數據時,有些方法無法被vue監測
push()
,pop()
,shift()
,unshift()
,splice()
,sort()
,reverse()
可被vue檢測到filter()
, concat()
, slice()
。這些不會改變原始數組,但總是返回一個新數組。當使用非變異(不改變原數組返回新數組)方法時,可以用新數組替換舊數組。
vue不能檢測以下變動的數組:
1、當你利用索引直接設置一個項時,vm.items[indexOfItem] = newValue
2、當你修改數組的長度時,例如: vm.items.length = newLength
this.$forceUpdate() //強制刷新
解決第一類問題:可以通過
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)
第二類問題可以通過
example1.items.splice(newLength)
對象屬性的添加或刪除
由於 Vue 會在初始化實例時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。
解決辦法:
使用 Vue.set(object, key, value)
方法將響應屬性添加到嵌套的對象上
Vue.set(vm.someObject, 'b', 2)
或者 this.$set(this.someObject,'b',2)
(這也是全局 Vue.set 方法的別名)
使用Object.assign()創建新對象,並且computed的屬性依賴於data的屬性,類似下面這種
data () { return { carts: this.$store.state.carts } }, computed: { getCarts() { for (let i = 0; i < this.carts.length; i++) { this.carts[i] = Object.assign({}, this.carts[i], { editState: false }); } this.carts = Object.assign({}, this.carts); return this.carts; } }
異步更新隊列
在最新的項目中遇到了這種情況,數據第一次獲取到了,也渲染了,但是第二次之后數據只有在再一次渲染頁面的時候更新,並不能實時更新。
網上查了資料才知道,Vue 異步執行 DOM 更新。只要觀察到數據變化,Vue 將開啟一個隊列,並緩沖在同一事件循環中發生的所有數據改變。如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。
解決辦法:
可在數據變化之后立即使用 Vue.nextTick(callback)
。這樣回調函數在 DOM 更新完成后就會調用
總結
- 遇到問題先谷歌和百度
- 猜測哪里出了問題,去看官方文檔原理
- vue數據變化視圖沒更新去看響應式原理,和數組變異原理。