目次
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
の使い方について解説します。
ゴール
親コンポーネント(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)を表示すると、以下のように描画されます。
まとめ
- propsを使わなくても、コンポーネント間のデータの共有が可能
-
provide/inject
を使うとバケツリレーの実装が防げる -
provide/inject
を多用しすぎると、コンポーネント間のデータの流れが複雑になりそう- ソースコードの可読性が低くなりそう
- 使い所は慎重に判断した方が良い