19_Vue如何監測到對象類型數據發生改變的?( 二 )


19_Vue如何監測到對象類型數據發生改變的?

文章插圖
我們雖然添加的是age,但是這里的意思是將原有屬性age覆蓋掉 , 使用這個新的age
我們來看下測試結果
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
出現bug的原因
  • 其實這個問題很好理解,我們看下錯誤原因

    • 19_Vue如何監測到對象類型數據發生改變的?

      文章插圖
  • 這是一個 無限遞歸產生的bug , 該方法一直無限的被調用,從而產生了這個錯誤
  • 為什么呢?
  • 我們仔細看下這段代碼

    1. 19_Vue如何監測到對象類型數據發生改變的?

      文章插圖
    2. 當,age屬性被訪問的時候,會調用get函數
    3. 調用get函數,會返回age
    4. 返回的過程當中,age是不是又被訪問了
    5. 從而產生死循環,無限遞歸
  • 為什么無法修改屬性呢?也是這個道理
所以,vue底層的數據代理,或者說數據加工沒有我們想的這么簡單,那么人家是怎么實現的呢
Observer
  • 在vue當中,有個接口叫做Observer , 這個接口用來監視頁面數據發生的變化
  • 不過他底層是如何進行監聽的呢
  • 我們寫不到底層那么詳細 , 只寫主要的部分
準備工作1、首先我們準備一個data,這里面存放了兩個屬性 , name和age
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
2、我們創建一個function ==> Observer
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
然后實例化這個 Observer , js當中,function是可以當做構造函數使用的
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
該函數需要一個屬性,從參數名可以看出,這是一個對象屬性
3、現在我們就來配置這個對象,首先我們需要獲取到 data這個對象當中的所有key值
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
4、對這個數組,進行循環
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
5、在迭代的過程當中,使用definedProperty進行數據代理
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
參數解析,為什么這里,添加數據的對象(參數1) 是 this?
  1. 使用this,那么就是給 this所指向的對象 ==> Observer;也就是我們剛剛實例化出來的對象

    • 19_Vue如何監測到對象類型數據發生改變的?

      文章插圖
  2. 給它添加屬性(property參數)
  3. 那么接下來我們就在 參數三 當中配置get和set了
6、get和set
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
數組當中是可以用字符串來獲取元素值的(很少)
完整代碼
// 這有一個對象,對象有兩個屬性let data = https://www.huyubaike.com/biancheng/{name:"waves",age: 0}// 實例化一個監視器對象let observer = new Observer(data);// 監視對象Observerfunction Observer(obj){// 1、獲取data當中的所有key值let properties = Object.keys(data); // ["name","age"]// 2、迭代 properties數組properties.forEach((property)=>{// 3、在迭代的過程當中,使用definedProperty進行數據代理Object.defineProperty(this,property,{// 配置get和setget(){// 很簡單,因為data沒有做數據代理,返回data[property]即可return data[property]; // data["name"] = waves},set(val){// 賦值即可data[property] = val}})})}總結
  1. 我們這里設置了一個data

    • 19_Vue如何監測到對象類型數據發生改變的?

      文章插圖
  2. 通過我們的一系列配置,data身上有的屬性,Observer實例身上也有
  3. 并且,這個observer身上的屬性都做了數據代理
  4. 當然,vue寫的比我們完善的多
  5. 比如,如果data當中還存在對象怎么辦?

19_Vue如何監測到對象類型數據發生改變的?

文章插圖
vue在這里寫了遞歸,一直找,找到這個屬性不再是對象為止
19_Vue如何監測到對象類型數據發生改變的?

文章插圖
數組也是一個道理,vue也能給你找出來,不過 關于數組和對象的代理,這二者的處理方式不同,下節會講解

推薦閱讀