最近做的項目是用vue寫租賃APP,其中再寫購物車頁面的時候,當調(diào)用后端刪除接口刪除數(shù)據(jù)之后,視圖并未及時更新,接下來就來細說一下這個問題的解決方法。
原理
每個組件實例都對應(yīng)一個 watcher 實例,它會在組件渲染的過程中把“接觸”過的數(shù)據(jù)屬性記錄為依賴。之后當依賴項的 setter 觸發(fā)時,會通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染。(摘自官網(wǎng))

data.png
- 關(guān)于數(shù)組數(shù)據(jù)變動我們操作數(shù)據(jù)的方法有很多,變動數(shù)據(jù)時,有些方法無法被vue監(jiān)測,有些可以。
例如這些操作數(shù)組的方法:
(1)push(),pop(),shift(),unshift(),splice(),sort(),reverse();
(2)vue2.0還增加個方法可以觀測Vue.set(items, indexOfItem, newValue)(推薦使用);
(3)filter(), concat(), slice()這些不會改變原始數(shù)組,但總是返回一個新數(shù)組。當使用非變異方法時,可以用新數(shù)組替換舊數(shù)組。 - 由于 JavaScript 的限制,Vue 不能檢測以下變動的數(shù)組:
(1)當你利用索引直接設(shè)置一個項時,vm.items[indexOfItem] = newValue;
(2)當你修改數(shù)組的長度時,例如: vm.items.length = newLength。
舉例說明
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是響應(yīng)性的
vm.items.length = 2 // 不是響應(yīng)性的
- 針對上面利用索引設(shè)置值的情況可以這樣解決:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// 或使用vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名
vm.$set(vm.items, indexOfItem, newValue)
- 針對修改長度的情況:
vm.items.splice(newLength)
- 當操作數(shù)據(jù)類型為對象時,由于 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 現(xiàn)在是響應(yīng)式的
vm.b = 2
// `vm.b` 不是響應(yīng)式的
對于已經(jīng)創(chuàng)建的實例,Vue 不能動態(tài)添加根級別的響應(yīng)式屬性。但是,可以使用 Vue.set(object, key, value)方法向嵌套對象添加響應(yīng)式屬性。例如,對于:
var vm = new Vue({
data: {
userProfile: {
name: 'hhh'
}
}
})
可以添加一個新的 age 屬性到嵌套的 userProfile 對象:
Vue.set(vm.userProfile, 'age', 17)
// 或
vm.$set(vm.userProfile, 'age', 17)
需要為已有對象賦予多個新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應(yīng)該用兩個對象的屬性創(chuàng)建一個新的對象:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 17,
color: 'blue'
})
this.$forceUpdate()
- 使用this.$forceUpdate();進行強制渲染,可以解決頁面v-for中修改item屬性值后頁面v-if不改變的問題。原因是因為數(shù)據(jù)層次太多,render函數(shù)沒有自動更新,需手動強制刷新。