Vue: Provide and Inject

因為工作中的Vue3專案都是用pinia來處理全域狀態問題,不過發現有時候有些跨元件狀態不會到整個應用都需要,但使用props又要用多層傳遞,所以筆記一下比較少用Vue本身的provide、inject機制。

以下使用Vue3 composition API語法為例:

Provide

// parent component
<script setup>
import { provide } from 'vue';

provide(key, value);  // 參數第一個是injection key可為string或Symbal型別, 第二個是實際要傳遞的資料
</script>

如果是要整個應用層級的provide則是這樣寫:

// app-level provide
import { createApp } from 'vue';

const app = createApp({ /.../ });
app.provide(key, value);

這邊有件有趣的事情,官方文件提到app-level provide可以進一步寫成plugins,印象中vue-router套件底層就是用app-level provide寫成。

Inject

// descendant component
<script setup>
import { inject } from 'vue';

const value = inject(key);
</script>

官方文件在這邊有特別說明,如果是響應式資料則會維持其響應式性質:

If the provided value is a ref, it will be injected as-is and will not be automatically unwrapped.

同時也建議若要傳遞響應式資料,可加上 readonly 確保資料不會意外被變動;也可一併提供”改變響應式資料的函式” (mutations),限制只能使用該函式變更資料的狀態。


References