關於vue無法偵聽數組及對象屬性的變化的解決方案


參考博文

https://ainyi.com/51

https://blog.csdn.net/qq_38280242/article/details/102807862

watch一般是可以監聽變量的變化的,但是對於數組或者對象在某些特定情況下是無法監聽到的。這種情況其實和雙向綁定的原理有關。Vue雙向綁定原理是利用js中的Object.defineproperty重定義對象的GET和SET方法,而同時這種方法存在着缺陷,就是只能監聽到對象內已有的值。詳細可見官方文檔https://cn.vuejs.org/v2/guide/reactivity.html

一、數組

1、可以監聽到的情況

如push、splice、=賦值(array=[1,2,3])

2、無法監聽到的情況

使用下標修改某個元素(這種比較常見)

array[index] = 1

object.a = 3

直接修改數組length

array.length = 5

3、解決方案

  • this.$set(array, index, data) - 這是個深度的修改,某些情況下可能導致你不希望的結果,因此最好還是慎用
this.dataArr = this.originArr
this.$set(this.dataArr, 0, {data: '修改第一個元素'})
console.log(this.dataArr)        
console.log(this.originArr)        //同樣的 源數組也會被修改 在某些情況下會導致你不希望的結果
  • 上面提到的splice方法進行增刪改
  • 利用臨時變量進行中轉
let tempArr = [...this.targetArr]
tempArr[0] = {data: 'test'}
this.targetArr = tempArr

二、對象

對象和數組都是js里的引用類型,在實際存儲中,數據是存儲在堆中的,利用存儲在棧里的對象名或者數組名的指針進行索引,因此也存在在淺拷貝和深拷貝以及等號賦值時,到底是僅僅新建了一個指針指向了同一份數據,還是兩個指針分別指向了兩份完全一樣的數據的問題

這部分內容參考https://juejin.im/post/59ac1c4ef265da248e75892b

1、可以監聽到的

對象的直接=賦值

this.obj = {name: 'test'}

2、無法監聽到的

對象屬性的增刪改

obj: {
    prop1: 'data1',
    prop2: 'data2'
}
...
//
this.obj.prop3 = 'data3'
//
delete this.obj.prop1
//
this.obj.prop1 = 'data4'

3、解決辦法

  • this.$set(obj, key ,value) - 可實現增、改
  • watch時添加deep:true深度監聽,只能監聽到屬性值的變化,新增、刪除屬性無法監聽
this.$watch('blog', this.getCatalog, {
    deep: true
    // immediate: true // 是否第一次觸發
  });
  • watch時直接監聽某個key
watch: {
  'obj.name'(curVal, oldVal) {
    // TODO
  }
}
  • object.assign()+直接=賦值
this.watchObj = Object.assign({}, this.watchObj, {
  name: 'xiaoyue',
  age: 15,
});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM