Vue 3 實戰:掌握 Provide / Inject 跨層級資料傳遞與響應式共享
在開發大型 Vue 應用時,我們常會遇到元件嵌套層級過深的問題。若要將祖先元件的資料傳給深層的曾孫元件,傳統的 props 必須像接力賽一樣層層傳遞,這不僅費時、費工,更會導致元件間產生不必要的耦合。
provide / inject 機制正是為了打破這種困境,實現 依賴注入(Dependency Injection),讓資料能直接跨越層級進行通訊。
基本用法:打破層層傳遞的僵局
這套機制由兩部分組成:父層負責 提供 provide,子層負責 注入 inject。
祖先元件:提供資料
在較外層的元件中,我們定義要分享出去的資料:
js
import { provide } from "vue";
provide("theme", "dark");深層子元件:接收資料
無論中間隔了多少層,子元件都能直接取出資料:
js
import { inject } from "vue";
const theme = inject("theme");安全建議
如果沒有父元件的 provide 時,子元件使用 inject 要噴警告! 因此,建議加上預設值較佳。
js
const theme = inject("theme", "light");進階應用:共享響應式狀態
傳遞靜態字串固然方便,但在實戰中,我們更常需要共享可以被更新的 響應式資料(ref / reactive)。
範例:全域計數器
當我們傳遞一個 ref 時,子元件接收到的也會是具備響應性的物件。
父元件 provide
js
import { ref, provide } from "vue";
const counter = ref(0);
provide("counter", counter);子元件 inject
js
import { inject } from "vue";
const counter = inject("counter", 10);
counter.value++;範例:封裝更新邏輯
雖然子元件可以直接修改 inject 進來的值,但在大型專案中,為了追蹤數據變化,建議遵循 誰提供,誰修改 的原則:將修改資料的方法一併 provide 出去。
父元件 provide:提供資料與方法
js
import { provide } from "vue";
function updateTheme(val) {
theme.value = val;
}
provide("updateTheme", updateTheme);子元件 inject:呼叫方法進行更新
js
import { inject } from "vue";
const updateTheme = inject("updateTheme");
updateTheme("light");總結:何時該使用 Provide / Inject?
- 開發通用元件庫:例如 Tabs、Accordion,父元件需要與多個不確定層級的子元件通訊。
- 全域主題切換:深層 UI 元素需要讀取目前的主題色、語言設定。
- 避免 Prop Drilling:當您的 Props 只是為了傳給下一個元件,自己卻完全沒用到時。
專業建議
雖然 provide / inject 很方便,但若資料流過於複雜,建議評估是否改用 Pinia 等狀態管理工具,以獲得更好的除錯支援與開發者工具(DevTools)追蹤。
