Vue 3.xカスタムイベントと$emitによるコンポーネント間通信

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>

まとめ

  1. コンポーネント間の通信方法の一つで、主に「子から親へデータを渡す」場合に使用します。
  2. 使用シナリオ:Aが親コンポーネント、Bが子コンポーネントの場合、BからAにデータを渡したい場合、AでBにカスタムイベントをバインドし、イベントの処理はAで実装します。
  3. カスタムイベントのバインド:
  • testは親コンポーネントに記述されたメソッドです
  • 第一の方法、親コンポーネント内で:
<Demo @myevent="test"/> または <Demo v-on:myevent="test"/>
  • 第二の方法、親コンポーネント内で:
<Demo ref="demo"/>
  mounted(){
    this.$refs.demo.$on('myevent',this.test)
  }
  • カスタムイベントを一度だけ実行したい場合は、once修飾子または$onceメソッドを使用できます。
  1. カスタムイベントのトリガー:
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])
}
  1. カスタムイベントの解除:
// 単一のカスタムイベントを解除
this.$off('myevent') 
// 複数のカスタムイベントを解除
this.$off(['myevent1','myevent2'])
// すべてのカスタムイベントを強制的に解除
this.$off()
  1. コンポーネントにネイティブDOMイベントをバインドするには、native修飾子を使用します。
<Student ref="student" @click.native="show"/>
  1. 注意点: this.$refs.componentName.$on('event', callback)でカスタムイベントをバインドする場合、コールバックはmethodsで定義するか、アロー関数を使用する必要があります。そうしないと、thisの参照が問題を起こす可能性があります!アロー関数でない場合、thisはカスタムイベントが定義されているコンポーネントを指します。

タグ: vue.js カスタムイベント コンポーネント通信 $emit v-on

6月25日 23:05 投稿