Vue.jsでは、アプリケーションを複数のコンポーネントに分割して開発するのが一般的です。その際に重要となるのが、コンポーネント間のデータのやりとりです。本記事では、props・emit・Vuex(もしくはPinia)などのストアを使って、適切にデータをやりとりする方法を解説します。
propsで親から子へデータを渡す
props
は、親コンポーネントから子コンポーネントへデータを渡すための仕組みです。読み取り専用であり、子コンポーネント側でpropsを直接書き換えることはできません。
// 親コンポーネント
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
parentMessage: 'こんにちは'
};
}
};
</script>
// 子コンポーネント(ChildComponent.vue)
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
props: ['message']
};
</script>
emitで子から親へイベント通知
emit
は、子コンポーネントから親コンポーネントに対してイベントを通知する仕組みです。ボタンのクリックなどを契機にデータを親に渡したいときに便利です。
// 子コンポーネント
<template>
<button @click="notifyParent">通知</button>
</template>
<script>
export default {
methods: {
notifyParent() {
this.$emit('child-event', '子からのメッセージ');
}
}
};
</script>
// 親コンポーネント
<template>
<ChildComponent @child-event="handleChildEvent" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
handleChildEvent(message) {
console.log('受け取ったメッセージ:', message);
}
}
};
</script>
storeを使ってグローバルにデータ共有
兄弟コンポーネントや階層の深いコンポーネント間でデータを共有したい場合は、VuexやPiniaなどの状態管理ライブラリを使うのが適しています。グローバルな状態として一元管理することで、アプリ全体のデータをスムーズに連携できます。
// Piniaの例(store.js)
import { defineStore } from 'pinia';
export const useMainStore = defineStore('main', {
state: () => ({
message: ''
}),
actions: {
updateMessage(newMsg) {
this.message = newMsg;
}
}
});
// 使用例(ComponentA.vue)
<template>
<button @click="store.updateMessage('更新されたメッセージ')">更新</button>
</template>
<script setup>
import { useMainStore } from './store';
const store = useMainStore();
</script>
// 使用例(ComponentB.vue)
<template>
<p>{{ store.message }}</p>
</template>
<script setup>
import { useMainStore } from './store';
const store = useMainStore();
</script>
使い分けのポイント
コンポーネント間の関係性やアプリの規模によって、以下のように使い分けるのが効果的です。
- 親 → 子:propsで値を渡す
- 子 → 親:emitでイベント通知
- 兄弟や遠い階層間:storeで共有
これらの方法を適切に使い分けることで、Vue.jsアプリのデータフローをシンプルに保ち、保守性の高いコードを書くことができます。