1. Vue3.0 裡為什麼要用 Proxy API 替代 defineProperty API?—— 響應式最佳化(高頻,重點!!!)Vue更新的重點。
- defineProperty API 的侷限性最大原因是它只能針對單例屬性做監聽。
- Vue2 中的響應式實現正是基於 defineProperty 中的 descriptor,對 data 中的屬性做了遍歷 + 遞迴,為每個屬性設定了 getter、setter。
- 這也就是為什麼 Vue 只能對 data 中預定義過的屬性做出響應的原因,在 Vue 中使用下標的方式直接修改屬性的值或者新增一個預先不存在的物件屬性是無法做到 setter 監聽的,這是 defineProperty 的侷限性。
- Proxy API 的監聽是針對一個物件的,那麼對這個物件的所有操作會進入監聽操作, 這就完全可以代理所有屬性,將會帶來很大的效能提升和更優的程式碼。
- Proxy 可以理解成,在目標物件之前架設一層 “攔截”,外界對該物件的訪問,都必須先透過這層攔截,因此提供了一種機制,可以對外界的訪問進行過濾和改寫。
響應式是惰性的
- 在 Vue2 中,對於一個深層屬性巢狀的物件,要劫持它內部深層次的變化,就需要遞迴遍歷這個物件,執行 Object.defineProperty 把每一層物件資料都變成響應式的,這無疑會有很大的效能消耗。
- 在 Vue3 中,使用 Proxy API 並不能監聽到物件內部深層次的屬性變化,因此它的處理方式是在 getter 中去遞迴響應式,這樣的好處是真正訪問到的內部屬性才會變成響應式,簡單的可以說是按需實現響應式,減少效能消耗。
基礎用法:
let datas = { num: 0 } let proxy = new Proxy(datas, { get(target, property) { return target[property] }, set(target, property, value) { target[property] += value } })