iT邦幫忙

2025 iThome 鐵人賽

DAY 17
1
Vue.js

在 Vue 過氣前要學的三十件事系列 第 17

在 Vue 過氣前要學的第十七件事 - 依賴注入 Provide/Inject

  • 分享至 

  • xImage
  •  

前言

在 Vue 過氣前要學的第十六件事 - 愛是雙向的 中,
我們提到了 vue 的雙向綁定,這僅止於父子關係的組件。
https://ithelp.ithome.com.tw/upload/images/20250916/20172784zN49hoDaa2.png

但如果今天這個元件跨了兩層,跨了三層嗎,
你還這樣一層一層傳嗎 傳到最後都不知道哪個是哪個了。

這也是你常會看到的 Prop Drilling

prop-drilling 示意圖,Root 代表父元素,Footer 代表子元素,DeepChild 代表孫子元素

你的中間層可能根本用不到這個 prop 但你還是為了使用而傳兩層。

因此我們就可以使用 Provide & Inject 來解決這個問題,
來看看怎麼用吧。

使用

基礎語法

<script setup>
import { provide } from 'vue'

provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
</script>
  • 第一個參數: 可以是一個 string 或是 Symbol
  • 第二個參數: 任意類型, 包括響應式狀態, ex: ref

使用時機

兩個組件屬於先後代關係,必須在同一條依賴鍊上,
如果這兩個組件沒有任何依賴關係,那是吃不到的。

https://ithelp.ithome.com.tw/upload/images/20250916/20172784ZC2xKU03mY.png

不存在同一條依賴鍊,無法注入( inject )

https://ithelp.ithome.com.tw/upload/images/20250916/201727847eX0LVfr9s.png

即便 Root 跟 Footer 只是父子層關係,但一樣可以使用 provide/inject

三層注入示例

<!-- App.vue ( 父層 ) -->
<script setup>
import { ref,provide } from 'vue';
import Comp from './Comp.vue';

const name = ref('')

provide('name',name)
//提供注入名為 'name' 和期望注入值為 `name` 這個 ref
</script>

<template>
  <h1>{{ name }}</h1>
  <p>職稱:前端工程師</p>
  <input v-model="name" placeholder="請輸入名字"/>
  <Comp></Comp> <!-- 使用中間層元件 -->
</template>
<!-- Comp.vue 子層元件 -->
<template>
  <ChildComp></ChildComp> <!-- 使用末層元件 -->
  <!-- 略 -->
</template>
<!-- Comp.vue 孫子層元件 -->
<script setup>
import { inject } from 'vue';

const name = inject('name')
// 使用 inject 接收注入名 'name' 的值
</script>

<template>
  <h1 v-if="name">{{name}}的鐵人賽</h1>
</template>

圖解資料傳遞差異


https://ithelp.ithome.com.tw/upload/images/20250916/20172784ol1PDRtruX.png
常見於父子組件 ( 通常傳遞不超過一層 )

https://ithelp.ithome.com.tw/upload/images/20250916/20172784wgGDGPc8Q0.png
常見於同一條依賴鍊 ( 爺傳父傳子皆可 )

https://ithelp.ithome.com.tw/upload/images/20250916/20172784OZ9MBEYsUv.png
常見於狀態管理工具 ( 可無視依賴關係,跨組件傳遞 )

結語

今天我們帶到了依賴注入這個觀念,講解了為何要避免 prop-drilling。

透過程式碼實際體驗一下如何使用 provide/inject
並在最後使用圖解來更好的了解常見的資料溝通是怎麼樣的流向。

依賴注入並不是什麼小叮噹的神奇道具,
https://ithelp.ithome.com.tw/upload/images/20250916/2017278495to9G78F1.png
其實從上面的圖解你可以知道,儘管我今天只有包一層,
我使用上面三種任一都可以傳遞資料下去。

但為什麼今天要區分,就是因為如果全都塞 Store 或是 provide
最後只會亂七八糟,完全沒有資料流可言,追溯來源都成了費力的事。

如果你喜歡這個系列或是想看我發瘋,歡迎按下 訂閱 一起走完這三十天吧。

一些回家作業

  1. 怎麼用一句話解釋依賴注入 ?
  2. 何謂 props-drilling,什麼情況下會發生 ?
  3. 除了依賴注入還有什麼方法可以做組件資料溝通 ?
  4. 什麼情況無法使用 provide/inject,什麼情況不建議用 provide/inject ?


上一篇
在 Vue 過氣前要學的第十六件事 - 愛是雙向的 / emit & v-model
下一篇
在 Vue 過氣前要學的第十八件事 - 我們必須更深入一點 / slot
系列文
在 Vue 過氣前要學的三十件事18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言