iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0
Vue.js

Vue3.6 的革新:深入理解 Composition API系列 第 7

Day 7: Vue 3 如何利用 Proxy 實現響應式系統

  • 分享至 

  • xImage
  •  

經過前一天 Proxy 的概念大致上有個雛形,或許我們可以思考一下:為什麼 Vue 3 需要 Proxy 呢?

A few minutes later...

其實 Vue 2 時期,響應式系統是基於 Object.defineProperty,這種方式無法攔截「新增或刪除屬性」,對陣列操作也有許多限制。

到了 Vue 3,核心團隊改採 ES6 Proxy,讓「監聽物件的存取與變更」變得完整、靈活,從根本上解決了 Vue 2 的痛點,這就是為什麼 Proxy === Vue 3 響應式的基石

今天先用程式碼跟大家說明 Proxy 怎麼做到響應式!

Vue 3 內部簡化版實作(簡化版)


以下是一個簡化版的 reactive(),能幫助我們直觀理解 Proxy 如何攔截 get / set 操作:

function reactive(target) {
  return new Proxy(target, {
    get(obj, key) {
      const value = Reflect.get(obj, key)
      console.log(`收集依賴: ${key}`)  // Vue 內部:把 key 與當前渲染函式建立關聯

      return value
    },
    set(obj, key, value) {
      const result = Reflect.set(obj, key, value)
      console.log(`觸發更新: ${key}`)  // Vue 內部:通知所有依賴該 key 的組件重新渲染

      return result
    }
  })
}

// 使用
const state = reactive({ count: 0 })
console.log(state.count) // 收集依賴: count
state.count++            // 觸發更新: count

這個範例雖然簡化,但也算已經說明了 Vue 3 的核心邏輯:

  • 讀取資料 → 收集依賴
  • 修改資料 → 觸發更新

圖像化理解:Proxy 就像一位全能管家


文字、程式碼好多,還是有點迷茫,怎麼辦?

嗯...簡單來說,我們可以把 Proxy 想成「全能管家」,老闆交代管家就只有兩項核心任務:

  1. 任務一:當你「讀取」資料時 (Get)
  2. 任務二:當你「修改」資料時 (Set)

這樣說很像又太過簡單扼要,程式碼展示過了,不然我們來說個關於 全能管家 Proxy 的故事吧!

故事是這樣的,幾年前有個富豪意外獲得一個超級寶箱,但是因為他忙也沒空看管,裡面的東西多了還是少了也不太確定,於是打聽到江湖上有一個工作效率超高的全能管家 Proxy
因為他的工作效率佳,所以特聘他幫忙看管裝滿金幣的寶箱!從那天起,任何人都不能再直接接觸寶箱了,所有進出款都必須透過這位管家。
Proxy 管家上工啦!

圖片中有個數字 1 ,它就是寶箱也就是我們在 Vue 中建立的原始 JavaScript 物件,例如 { count: 0, user: { name: 'kuku' } }。它靜靜地存放你的資料,因為本身很「被動」,你動了它,它也不會主動通知任何人,畢竟它只是一個裝載資料的物件。
圖片中的數字 2 ,就是被聘請看管寶箱的管家 Proxy ,因為寶箱無法表達所以藉由管家來掌管寶箱內的資料讀取異動。

突然有天,家裡有客人來訪,他看到寶箱好想好想知道寶箱裡有什麼,於是向管家詢問。管家一邊拿出金幣給他看,一邊拿出一個小本本,偷偷記下:「A 組件對『金幣數量』很感興趣。」
Proxy 管家「讀取」資料

Proxy 紀錄的行為叫做「依賴收集 (Dependency Tracking)」。
當 Vue 組件畫面 <template> 第一次渲染時,需要讀取 state.count 的值;這個「讀取」操作會被管家 (Proxy) 攔截,管家知道是哪個組件正在讀取哪個資料,於是就建立了一個關聯:「這個組件依賴於這個資料」。

看完沒多久,客人突然給了管家一顆新的寶石,讓他放進寶箱。管家放入寶石後,立刻拿出大聲公,對著剛剛在他的小本本上記錄過的所有人(A 組件)大喊:「注意!寶箱裡的財產變了!快來看看新的樣子!」
寶箱內容不同,管家立即修改公告天下

這叫做「觸發更新 (Trigger Update)」。當程式碼執行 state.count++ 時,這個「寫入」操作也被管家 Proxy 攔截了。
管家完成資料更新後,會去翻閱他的小本本,找到所有依賴 state.count 的組件,並通知它們:「你關心的資料變了,你需要重新渲染畫面了!」

正是因為有了這位管家,Vue 3 才能精準又高效地知道,當資料變動時,應該更新畫面的哪一個部分,而不是無腦地刷新整個頁面。

好了!今天故事講完了,對於管家有沒有更加熟悉呢?


上一篇
Day 6: Proxy 的底層實現
下一篇
Day 8: 使用 computed 與 watch 資料監控與處理
系列文
Vue3.6 的革新:深入理解 Composition API8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言