【Vue.js】vm.$emit とそれを用いた子コンポーネントから親コンポーネントへのデータ渡し
vm.$emit
は引数で指定したイベントを発火させる。
これを使って、親コンポーネント内で v-on
ディレクティブを使って登録したカスタムイベントを発火させることで、子から親へのデータ渡しが実現できる。
例えば、親コンポーネントである App.vue
を以下のように記述する。
<template> <div id="app"> <!-- カスタムイベントfavを登録。favが発火したらaddToFavoriteを実行 --> <Posts @fav="addToFavorite"/> </div> </template> <script> import Posts from './components/Posts.vue' export default { name: 'app', components: { Posts }, data: function () { return { 'favorites': [] } }, methods: { // コールバックとして指定されているメソッド // postTitleには子コンポーネントから渡されるデータが入ってくる addToFavorite: function(postTitle) { this.favorites.push(postTitle); console.log(this.favorites); } } } </script>
methods
オブジェクトには addToFavorite
メソッドを定義しておき、<Posts @fav="addToFavorite"/>
でカスタムイベント fav
を登録し、 fav
が発火したら addToFavorite
メソッドを実行するように記述。
そして、子コンポーネントである Posts.vue
は以下のようにする。
<template> <div class="posts"> <ul> <!-- li要素クリックでPostsコンポーネントのaddToFavメソッドが発火する --> <li v-for="(post, index) in posts" :key="index" @click="addToFav"> {{ post.title }} </li> </ul> </div> </template> <script> export default { name: 'Posts', data: function () { return { 'posts': [ {'title': 'タイトル1'}, {'title': 'タイトル2'}, {'title': 'タイトル3'}, ] } }, methods: { addToFav: function (e) { // vm.$emitでカスタムイベントfavを発火させる // 第二引数のデータはfavで指定しているコールバックに渡される this.$emit('fav', e.path[0].innerText); } } } </script>
this.$emit('fav', e.path[0].innerText);
の部分で親コンポーネントで登録したカスタムイベント fav
を発火させる。
ちなみに e.path[0].innerText
はクリックした要素のテキストを取得していて、これをコールバックとして指定している親コンポーネントのメソッド addToFavorite
に渡している。