Vue.set向對象裏增加多層數組屬性不生效的情況解說

屬性多層數組數據的添加修改

一、爲什麼需要使用Vue.set?

vue中不能檢測到數組的一些變化,比如一下兩種:

1、數組長度的變化 vm.arr.length = 100
  
2、數組通過索引值修改內容 vm.arr[1] = ‘aa’

那麼爲什麼vue要做成這樣,不去監聽數組的變化,數組在日常中使用頻率還是比較高的,這個問題其實尤大說過,是爲了性能,假設我們新建了一個數組,長度是1000 但是隻使用了前幾個 ,去實現頁面的響應式監聽,從數組改變到頁面輸出一共需要遍歷兩遍數組,會增加性能消耗,這可能就是不去監聽某一項數組數據變化的原因吧。
以下是vue observer的的源碼,判斷是數組了,會停止對數據屬性的監測。
在這裏插入圖片描述
  所以vue提供了Vue.set 方法彌補這些不足,Vue.set同vm.$set(target,key,value):可以動態的給數組、對象添加和修改數據,並更新視圖中數據的顯示。

vue在構造函數new Vue()時,就通過Object.defineProperty中的getter和setter 這兩個方法,完成了對數據的綁定。所以直接通過vm.arr[1] = ‘aa’的方法,無法修改值去觸發vue中視圖的更新,必須還得通過Object.defineProperty的方法去改變,而Vue.set()就封裝了js底層的Object.defineProperty方法。

所以我們需要利用Vue.set() 響應式新增與修改數據。
  
二、最近項目中使用到了樹形表格,即多層嵌套的數據,類似於這樣的頁面展示。數據結構如下:

obj:[
        {
          id:'1',
          type:'1',
          children:[
            {
              id:'1-1',
              type:'1-1',
            }
          ]
        }
      ]

在這裏插入圖片描述
在每一層數據的數據量都比較大的時候,不能使用一次性加載所有數據,需要優化加載,點擊table的expand,即@expand-change方法獲取下一層數據,那麼就需要給下一層數據增加children屬性,那麼我們肯定會想到一下幾種方法:

  1. this.$set(this.obj[index],‘children’,[…res.items])
  2. this.obj[index].children = []
    this.obj[index].children.splice(0,0,…res.items) //或者push方法
    3.使用foreach方法,循環res.items使用 this.$set(this.obj[index].children,index,res.items[index])
    我使用了這幾種方法,甚至是組合使用了,但是結果不是很好,數據是增加上了,但是並沒有響應式的增加上,頁面都沒有展示出相應的數據,查看結構時,發現到第三層的時候,增加的children已經沒有{ob:Observer},ob_: Observer是vue這個框架對數據設置的監控器,有這個屬性,才能監聽到數據的變化。
    找了很久都不可以。最終嘗試了以下方法才得以解決:
//給第三層增加數據
this.$set(this.obj[level1Index].children[level2Index],'children',[])
//使用foreach 將數組的每一項添加爲響應式數據
res.items.forEach((item,index)=>{
	this.obj[level1Index].children[level2Index]
	this.$set(this.obj[level1Index].children[level2Index].children,index,item)
})

首先先添加children數組爲響應式,再去將數組中的每一項也添加爲響應式,頁面變可以正常顯示啦 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章