【Vue.js】provide/injectの仕組みと応用例|親子コンポーネント間の依存関係を整理する設計

【Vue.js】provide/injectの仕組みと応用例|親子コンポーネント間の依存関係を整理する設計 Vue.js

Vue.jsで親子コンポーネント間の値の受け渡しを行う際、propsemitが主に使われますが、ツリー構造が深くなるとコードが煩雑になりがちです。そんなときに役立つのがprovide/injectの仕組みです。本記事では、基本的な使い方から、実践的な応用例、設計時の注意点まで詳しく解説します。

provide/injectとは?

provide/injectは、Vue.jsの依存注入機能(Dependency Injection)です。祖先コンポーネントがprovideで値を提供し、子孫コンポーネントがinjectで受け取ります。これにより、深い階層構造においても中間のpropsを省略でき、スッキリした設計が可能になります。

基本的な使い方

まずはシンプルな例で使い方を確認しましょう。

親コンポーネント(Provider)

<script setup>
import { provide } from 'vue';
const userName = '山田太郎';
provide('user', userName);
</script>

子コンポーネント(Injector)

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

<template>
  <p>こんにちは、{{ user }}さん</p>
</template>

このように、userというキーで値を共有できます。

応用例:複数コンポーネント間で共通データを共有

たとえば、テーマカラーや言語設定などの共通設定を、アプリケーション全体で扱いたい場合にprovide/injectが便利です。

App.vue で提供

<script setup>
import { provide, reactive } from 'vue';

const settings = reactive({
  lang: 'ja',
  theme: 'dark'
});

provide('settings', settings);
</script>

どこかの子孫コンポーネントで取得

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

const settings = inject('settings');
</script>

<template>
  <div>
    使用中の言語:{{ settings.lang }} / テーマ:{{ settings.theme }}
  </div>
</template>

reactiveと組み合わせることで、変更もリアクティブに反映されます。

注意点と設計のポイント

provide/injectは便利な反面、過剰に使うと依存関係が見えづらくなる恐れがあります。以下の点に注意しましょう。

  • 共通状態はVuexやPiniaと比較検討する
  • 意図的に限定的な用途に使う(テーマ・翻訳・認証など)
  • injectした値が存在しない場合のデフォルト値やnullチェックを忘れない

まとめ

provide/injectは、Vue.jsのコンポーネント設計を柔軟にし、特に大規模なアプリケーション開発においてpropsの煩雑さを軽減してくれる強力な仕組みです。使い方を誤らずに、責務を明確に保った設計を心がければ、メンテナンス性の高いコードを実現できます。