LoginSignup
6
3

More than 1 year has passed since last update.

【Vue】provide/injectについて

Last updated at Posted at 2022-12-26
1 / 20

目次

1.はじめに
2.propsによるデータの受け渡し方法
3.provide/injectとは
4.使い方
5.まとめ


はじめに

この記事では、Vueのprovide/injectについて書いています。


propsによるデータの受け渡し方法

Vueでは、コンポーネント間のデータ渡しをするときは、propsを使われるのが一般的です。


親コンポーネントから子コンポーネントへpropsを受け渡すことで、コンポーネント間のデータの共有が可能です。

コンポーネントの階層が深い場合に、propsを使うとバケツリレーのように各コンポーネントにprops定義が必要になります。



親コンポーネントから孫コンポーネントへデータの共有をする場合は、間の子コンポーネントでもpropsの定義が必要になってしまい、vuex・piniaなどの状態管理の外部ライブラリが使われるケースがあります。 


provide/injectとは

provide/injectを使うことで、propsを使わずにコンポーネント間のデータの共有が可能となります。

親コンポーネントと孫コンポーネントでのみデータを共有したい場合に、中間の子コンポーネントへのデータの注入・コード修正も不要になります。



親となるコンポーネントでprovide(共有したいデータの定義)を実装し、受け取りたいコンポーネント側でinject(共有データの注入)を実装することで、コンポーネント間のデータ共有が可能になります。また、propsのようなバケツリレー実装が防げます

引用元:https://v3.ja.vuejs.org/guide/component-provide-inject.html


使い方

今回は、親コンポーネントで定義したデータを孫コンポーネントに渡すコードを例に、provide/injectの使い方について解説します。


ゴール

image.png


親コンポーネント(Parent.vue)の実装

provideを使用すると、任意の値をキー文字列と一緒に保持することができます。親コンポーネントで、provideを実装することで、その配下のコンポーネントでデータの注入(inject)が可能になります。

※以降の実装では、styleタグの実装を省略している。


<template>
  <div class="box">
    <p>親コンポーネント: {{ name }}</p>
    <Child />
  </div>
</template>

<script>
import { provide, ref } from 'vue';
import Child from './Child.vue';

export default {
  name: 'Parent',
  components: {
    Child,
  },
  setup() {
    // 孫に渡したいデータ
    const name = ref('テスト太郎');
    // 第一引数:キーを指定
    // 第二引数:共有したいデータ
    provide('inputName', name);
    return {
      name,
    };
  },
};
</script>

子コンポーネント(Child.vue)の実装

子コンポーネントではデータを注入(inject)しないため、孫コンポーネントを表示するだけの実装になっています。


<template>
  <div class="box">
    <p>子コンポーネント</p>
    <GrandChild />
  </div>
</template>

<script>
import GrandChild from './GrandChild.vue';

export default {
  name: 'Child',
  components: {
    GrandChild,
  },
};
</script>

孫コンポーネント(GrandChild.vue)の実装

孫コンポーネントではデータを注入するため、injectを使用して共有データを参照しています。injectメソッドでは、キーを引数に指定することで、受け取りたいデータを特定し、参照することが可能です。

今回の場合、親コンポーネントで、inputNameをキーに指定しているため、inject時にも同様のキーを指定します。


<template>
  <div class="box">
    <p>孫コンポーネント: {{ name }}</p>
  </div>
</template>

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

export default {
  name: 'GrandChild',
  setup() {
    const name = inject('inputName');
    return {
      name,
    };
  },
};
</script>


以上で、親コンポーネント(Parent.vue)を表示すると、以下のように描画されます。

image.png


まとめ

  • propsを使わなくても、コンポーネント間のデータの共有が可能
  • provide/injectを使うとバケツリレーの実装が防げる
  • provide/injectを多用しすぎると、コンポーネント間のデータの流れが複雑になりそう
    • ソースコードの可読性が低くなりそう
    • 使い所は慎重に判断した方が良い
6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3