LoginSignup
1

【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を多用しすぎると、コンポーネント間のデータの流れが複雑になりそう
    • ソースコードの可読性が低くなりそう
    • 使い所は慎重に判断した方が良い

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
What you can do with signing up
1