1. 程式人生 > 其它 >vue data裡的資料的變化

vue data裡的資料的變化

實際在開發過程中發現,我們列印data裡的資料的時候會發現,他不是我們所看到的以往的很平常的格式,他是一個proxy的格式的,如下圖:

也就是說無論是什麼型別的資料,都會在外面包一層proxy的包裝;

這個是作什麼的呢?

查資料——————————————

經過這一頓操作之後,資料就可以恢復正常的型別了,

JSON.parse(JSON.stringify(val))

關於Proxy:

Proxy可以理解成,在目標物件之前架設一層 "攔截",當外界對該物件訪問的時候,都必須經過這層攔截,而Proxy就充當了這種機制,類似於代理的含義,它可以對外界訪問物件之前進行過濾和改寫該物件。

如果對vue2.0瞭解或看過原始碼的人都知道,vue2.0中使用 Object.defineProperty()方法對該物件通過 遞迴+遍歷的方式來實現對資料的監控的,

當我們使用陣列的方法或改變陣列的下標是不能重新觸發 Object.defineProperty中的set()方法的,因此就做不到實時響應了。所以使用 Object.defineProperty 存在如下缺點:

1. 監聽陣列的方法不能觸發Object.defineProperty方法中的set操作(如果要監聽的到話,需要重新編寫陣列的方法)。
2. 必須遍歷每個物件的每個屬性,如果物件巢狀很深的話,需要使用遞迴呼叫。

但是vue2.0就是用$set()方法去解決上面的這個問題,Vue3.0呢進行了升級,那就是Proxy。

Proxy基本語法

const obj = new Proxy(target, handler);

這裡就和上面的截圖對應上了,有木有發現呢~,再來一個詳細的圖;

引數說明如下:

target:被代理物件。
handler:是一個物件,聲明瞭代理target的一些操作。
obj:是被代理完成之後返回的物件。

但是當外界每次對obj進行操作時,就會執行handler物件上的一些方法。handler中常用的物件方法如下:

1. get(target, propKey, receiver)
2. set(target, propKey, value, receiver)
3. has(target, propKey)
4. construct(target, args):
5. apply(target, object, args)

如下程式碼演示:

const target = {
  name: 'kongzhi'
};

const handler = {
  get: function(target, key) {
    console.log(`${key} 被讀取`);
    return target[key];
  },
  set: function(target, key, value) {
    console.log(`${key} 被設定為 ${value}`);
    target[key] = value;
  }
};

const testObj = new Proxy(target, handler);

/*
  獲取testObj中name屬性值
  會自動執行 get函式後 列印資訊:name 被讀取 及輸出名字 kongzhi
*/
console.log(testObj.name);

/*
 改變target中的name屬性值
 列印資訊如下: name 被設定為 111 
*/
testObj.name = 111;

console.log(target.name); // 輸出 111

如上程式碼所示:也就是說 target是被代理的物件,handler是代理target的,那麼handler上面有set和get方法,當每次列印target中的name屬性值的時候會自動執行handler中get函式方法,當每次設定 target.name 屬性值的時候,會自動呼叫 handler中的set方法,因此target物件對應的屬性值會發生改變,同時改變後的 testObj物件也會發生改變。同理改變返回後 testObj物件中的屬性也會改變原物件target的屬性的,因為物件是引用型別的,是同一個引用的。如果這樣還是不好理解的話,可以簡單的看如下程式碼應該可以理解了:

const target = {
  name: 'kongzhi'
};

const testA = target;

testA.name = 'xxx';

console.log(testA.name); // 列印 xxx

console.log(target.name); // 列印 xxx

大概就是這樣的,vue3.0的升級,可直接監聽陣列型別的資料變化
監聽的目標為物件本身,不需要像Object.defineProperty一樣遍歷每個屬性,有一定的效能提升。