在 Vue3 中處理資料時,常常會有資料不斷向子組件傳遞的需求,一旦層級越來越多、維護上就越來越麻煩,所以這篇我們請 provide
& inject
來 解決這個問題。
接下來的程式碼都是以 script setup
為主。
使用 provide
就可以將資料往下傳遞,寫法為:
provide(key, value)
這個 key
待會我們在子組件接收資料時會用到。
實際的範例如下:
import { ref, provide } from "vue"
const age = ref(16)
provide("age", age)
這樣就往下傳了,接著看 inject
如何接收資料。
inject
寫法:
inject(key, default)
實際的範例如下:
import { inject } from "vue"
const age = inject("age", 12)
這邊因為傳下來的值用 ref()
包裝過,所以依然保有響應式的特性,所以在子組件修改過後、上層也同樣會被影響。
如果希望值不能修改,可以在 provide
傳遞時加上 readonly:
provide("age", readonly(age))
回到 能直接修改父層傳遞的資料這塊,雖然沒加 readonly 是可以直接修改的,不過建議還是使用 單向資料流
的概念來修改資料。
所以下面的範例中,我們會將一個變數 number
和 add
函式傳入子層,如果想要修改 number
的話,都必須透過 add
這個函式:
// 父層
import { provide, ref } from "vue"
const number = ref(1)
const addNumber = () => {
number.value ++
}
provide("number", number)
provide("addNumber", addNumber)
// 子層
<script setup>
import { inject } from "vue"
const number = inject("number")
const addNumber = inject("addNumber")
</script>
<template>
<h1> {{ number }} </h1>
<button @click="addNumber">add</button>
</template>
同樣可以達成效果,維護上也更加清楚。
文末提醒使用 provide
& inject
的注意事項:
provide
& inject
只能在生命週期 setup()
中使用。