Vue.jsにおけるコンポーネント間のイベント通信
Vue.jsでは、クリックイベント@clickやキーボードイベント@keyupなど、様々なイベントがあります。
v-on:ディレクティブは@と省略して記述できます。
一、親コンポーネントから子コンポーネントへのデータ伝達
1. 子コンポーネントで親コンポーネントのデータを利用する
親コンポーネントで子コンポーネントを使用する際に、カスタムイベントを定義します。
<template>
<div>
<!-- カスタムイベントparentEventを定義し、handleEventメソッドを実行 -->
<my-component @parentEvent="handleEvent"></my-component>
</div>
</template>
<script>
import MyComponent from '../components/MyComponent'
export default {
data() {
return {
message: "メインページ"
}
},
components: {
MyComponent
},
methods: {
handleEvent() {
alert("メインコンポーネントのhandleEventメソッドが実行されました")
}
}
};
</script>
2. 子コンポーネントで親コンポーネントのメソッドを呼び出す
子コンポーネント側ではthis.$emitを使用して親コンポーネントのイベントを呼び出します。
<template>
<div>
<button @click="triggerParentEvent">親コンポーネントのメソッドを実行</button>
</div>
</template>
<script>
export default {
data() {
return {
componentMessage: "ヘッダーコンポーネント",
}
},
methods: {
triggerParentEvent() {
// 親コンポーネントで定義したparentEventイベントを呼び出す
this.$emit("parentEvent")
}
}
}
</script>
二、子コンポーネントから親コンポーネントへのデータ伝達
1. 親コンポーネントで子コンポーネントのデータを受け取る
親コンポーネント側でメソッドを定義し、引数を追加して子コンポーネントからの値を受け取ります。
<template>
<div>
<my-component @parentEvent="handleEvent"></my-component>
</div>
</template>
<script>
import MyComponent from '../components/MyComponent'
export default {
data() {
return {
message: "メインページ"
}
},
components: {
MyComponent
},
methods: {
// 引数valueで子コンポーネントからの値を受け取る
handleEvent(value) {
alert(value)
}
}
};
</script>
2. 子コンポーネントで値を親に渡す
子コンポーネントがイベントを呼び出す際に、親に渡す値を引数として指定します。
<template>
<div>
<button @click="triggerParentEvent">親コンポーネントに値を渡す</button>
</div>
</template>
<script>
export default {
data() {
return {
componentMessage: "ヘッダーコンポーネント",
}
},
methods: {
triggerParentEvent() {
// 親コンポーネントのparentEventイベントを呼び出し、第二引数で値を渡す
this.$emit("parentEvent","子コンポーネントからの値です")
}
}
}
</script>
まとめ
- コンポーネント間の通信方法の一つで、主に「子から親へデータを渡す」場合に使用します。
- 使用シナリオ:Aが親コンポーネント、Bが子コンポーネントの場合、BからAにデータを渡したい場合、AでBにカスタムイベントをバインドし、イベントの処理はAで実装します。
- カスタムイベントのバインド:
- testは親コンポーネントに記述されたメソッドです
- 第一の方法、親コンポーネント内で:
<Demo @myevent="test"/> または <Demo v-on:myevent="test"/>
- 第二の方法、親コンポーネント内で:
<Demo ref="demo"/>
mounted(){
this.$refs.demo.$on('myevent',this.test)
}
- カスタムイベントを一度だけ実行したい場合は、
once修飾子または$onceメソッドを使用できます。
- カスタムイベントのトリガー:
this.$emit('イベント名',データ)
// ここでのデータは文字列、オブジェクト、配列などが可能
// 単一パラメータ
this.$emit('イベント名',this.name)
// 親コンポーネントでの受け取り
handleValue(name){
console.log(name)
}
// 複数パラメータ(個別渡し)
this.$emit('イベント名',this.name,this.age)
// 親コンポーネントでの受け取り
handleValue(name, age){
console.log(name, age)
}
// パラメータが多い場合、...paramsを使用
handleValue(name, ...params){
console.log(name, ...params)
}
// 複数パラメータ(オブジェクト形式)
student: {name:"Tanaka", age:25}
this.$emit('イベント名',this.student)
// 親コンポーネントでの受け取り
handleValue(student){
console.log(student.name)
}
// 複数パラメータ(配列形式)
hobbies: ["読書", "旅行", "映画鑑賞"]
this.$emit('イベント名',this.hobbies)
// 親コンポーネントでの受け取り
handleValue(hobbies){
console.log(hobbies[0])
}
- カスタムイベントの解除:
// 単一のカスタムイベントを解除
this.$off('myevent')
// 複数のカスタムイベントを解除
this.$off(['myevent1','myevent2'])
// すべてのカスタムイベントを強制的に解除
this.$off()
- コンポーネントにネイティブDOMイベントをバインドするには、
native修飾子を使用します。
<Student ref="student" @click.native="show"/>
- 注意点:
this.$refs.componentName.$on('event', callback)でカスタムイベントをバインドする場合、コールバックはmethodsで定義するか、アロー関数を使用する必要があります。そうしないと、thisの参照が問題を起こす可能性があります!アロー関数でない場合、thisはカスタムイベントが定義されているコンポーネントを指します。