Skip to content
On this page

Vue3 依賴注入 provide && inject

說明

一般而言,組件之間的資料傳遞,可以使用 props 來達成,不過一旦層級過多的時候,props 就要逐層向下傳遞,會越來越麻煩且複雜。

provideinject 可以解決這個問題,它可以提供一個「源頭」,子組件們可以藉由同一個源頭取得對應的資料,且沒有層級分別,都可以取得,就不用逐層傳遞資料了。

圖片出處

基本操作

父層 provide (提供)

使用 provide() 為資料註冊一個源頭名稱,供子組件注入取得資料。 可以多次使用 provide 註冊多個資料,資料也可以是 資料響應 reactive && ref

provide(源頭名稱, 資料)

vue
<script setup>
import Comp from './Comp.vue'
import { ref, reactive, provide } from 'vue'

const data = ref(0)
provide('parentData', data)
provide('state', '123')
</script>

<template>
  <h1 @click="data++">Parent</h1>
  <Comp />
</template>

子層 inject (注入)

使用 inject() 來接上層註冊的資料,上層使用什麼類型註冊,資料就是什麼類型。

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

const parentData = inject('parentData')
const state = inject('state')

console.log(parentData.value, state)
</script>

<template>
  <h1>child</h1>
  <div>
    {{ parentData }}
  </div>
</template>

響應資料注入與資料修改

為維持「單向資料流」,資料都應由源頭修改,這樣會較容易維護。「提供」不只是提供 資料 也可以提供 函式 供子組件操作狀態。

父層

「父層」聲明了一個源頭,為 物件 型別,資料以 資料響應 reactive && ref 提供,在 物件 中同時提供了修改源頭資料的方法。

vue
<script setup>
import Comp from './Comp.vue'
import { ref, provide } from 'vue'

const num = ref(0)
function resetNum() {
  num.value = 0
}
function plusNum() {
  num.value++
}
function customNum(newNum) {
  num.value = newNum
}
provide('num', {
  value: num,
  customNum,
  plusNum,
  resetNum,
})
</script>

<template>
  <Comp />
</template>

子組件

inject() 取得了「源頭」資料,內部包含了操作源頭資料的方法,「子組件」應透過方法操作資料,來落實單向資料流!

vue
<script setup>
import { inject } from 'vue'
const num = inject('num')
</script>

<template>
  <div>
    <button @click="num.customNum(999)">num = 999</button>
    <button @click="num.plusNum">+</button>
    <button @click="num.resetNum">reset</button>

    {{ num.value }}
  </div>
</template>

Reference