親コンポーネントと子コンポーネントでデータをやりとりする方法について紹介

Photo by Christopher Robin Ebbinghaus on Unsplash

こんにちは!
個人開発者の南です。

VueJsでコンポーネントごとにわけている時に、コンポーネントにあるデータを他のコンポーネントに分けるにはどうすればいいのだろう?っと思ったことがありました。

今回は忘れた時に思い出せる用のメモとして、コンポーネント間のデータのやりとりの方法について紹介します!

コンポーネント間でデータをやりとりする方法

コンポーネント間でデータをやりとりするために必要なことは、次の2つです。

・v-bind:valueで渡したい値を指定。
・$emitで更新した値を親のコンポーネントに渡す。

の2点を基本的には、行っていきます。

実際のコードを書くと次のような感じになります。

そして、別のコンポーネントは下記のように記述します。

作成したコンポーネントの実際の動き

実際に表示してみると、親コンポーネントは下記のように表示されます。


そして、親コンポーネントの「値を更新する」という部分をクリックすると、子コンポーネント(another-component)に移動します。


そして、子コンポーネントのフォームの値を変更します。


値の更新が終わったら、「更新」をクリックします。

すると、親コンポーネントの表示に切り替わります。

表示が切り替わった後は、子コンポーネントで変更した内容が反映されています。


これが上記のコンポーネントの基本的な流れです。

コードの解説

動きがわかったところで、コードの解説をしていきます。

ここでは、次の順番にコードを解説していきます。

1.親コンポーネントのコードについて
2.子コンポーネントのコードについて

親コンポーネントのコードについて

最初のところで紹介したように親コンポーネントは次のようなコードでした。

この親コンポーネントのコードでは、次のような処理を書いています。。

・v-ifを使ってpageの数字によって表示するものを切り替える。
・「値を更新する」というボタンが押されたら画面を切り替える。
・子コンポーネントにデータをバインドして、現在のデータを渡す。
・子コンポーネントから、更新されたという通知を受け取る。
・通知を受け取ったら、データの更新する。

それぞれ順に紹介していきます。

v-ifを使ってpageの数字によって表示するものを切り替える。

まずは、v-ifで表示するページを切り分けています。

コード中の「data()」の箇所で定義されている「page」が0の時は、親コンポーネントを表示。

1の時は、子コンポーネントを表示という風にしています。

「値を更新する」というボタンが押されたら画面を切り替える。

「値を更新する」というボタンがクリックされると、「methods」の中で定義されいてる「change_form()」という関数が走ります。

この関数はクリックされると、「page」の値を0から1に変更するという処理になっています。

これにより、子コンポーネントの表示に切り替わります。

子コンポーネントにデータをバインドして、現在のデータを渡す。

親コンポーネントに記述されている「」ですが、よくよくみると「:desc」といったものが記述されています。

実は、これで子コンポーネントに親コンポーネントのデータを渡しています。

「:desc=”post_data.desc”」は、子コンポーネントでは、「this.desc」で参照することができます。

「:post_title=”post_data.post_title”」は、子コンポーネントでは、「this.post_title」というように参照できます。

つまり、「:」以降に参照したい時の名前を定義して、「=」以降にどんなデータを渡したいかを定義します。

これによって、子コンポーネントでは「:」以降で定義した名前でデータを使うことができます。

あとで解説しますが、子コンポーネントでは、次のようにデータを参照します。

子コンポーネントから、更新されたという通知を受け取る。

親コンポーネントに記述されている「」ですが、「:desc」にも、よくよくみると「@send_data_from_another_form=”set_data”」といったものが記述されています。

これは、子コンポーネントで記述されている下記のコードに対応しています。

あとで解説しますが、子コンポーネントの更新ボタンをクリックすると、「submit」関数が走るようになっています。

この中で、「this.$emit( ‘send_data_from_another_form’, this )」の中にある、「send_data_from_another_form」と親コンポーネントの「@send_data_from_another_form」が対応しています。

これは、JavaScriptのイベントリスナーようなもので、子コンポーネントで「this.$emit( ‘send_data_from_another_form’, this )」が走ると、その後に親コンポーネントの「@send_data_from_another_form」で定義されている「set_data」関数が走ります。

つまり、子コンポーネントで「$emit」して、「@」でその関数が走ったという通知を受け取ることができます。

通知を受け取ったら、データの更新する。

子コンポーネントで「this.$emit( ‘send_data_from_another_form’, this )」が走ると、親コンポーネントで定義されている「set_data」関数が走ります。

あとは、最初引数の中で子コンポーネントで更新されたデータが渡ってくるので、それをローカルのデータにセットすることで値を更新することができます。

親コンポーネントのコードの解説は以上になります。

子コンポーネントのコードについて

次は子コンポーネントのコードについてです。

子コンポーネントのコードは下記のようなコードでした。

このコードでは、次のようなことをしています。

1.propsでどんなデータが渡ってくるかを定義。
2.mountedで、親コンポーネントのデータをセット。
3.更新ボタンがクリックされたら、submit関数を走らせる。
4.submit内で、v-modelで定義されている、inputの内容を反映する。
5.$emitで親コンポーネントにデータを渡す。

propsでどんなデータが渡ってくるかを定義。

親コンポーネントでは、次のように「:desc」のように子コンポーネントに渡すデータを定義していました。

子コンポーネントでは必ず「props」を使って、どんなデータが渡ってくるかを定義しておく必要があります。

「props」に定義することで、親コンポーネントから渡されたデータを使用することができます。

mountedで、親コンポーネントのデータをセット。

「mounted」関数は画面が表示された時に、走る関数です。

ここでは、次のように親コンポーネントのデータを反映するという処理をしています。

更新ボタンがクリックされたら、submit関数を走らせる。

「更新」ボタンをクリックすることで、「@click=”submit”」で定義されているsubmit関数が走ります。

#submit関数を走らせる。

$emitで親コンポーネントにデータを渡す。

submit関数が走ったら、あとは関数内の「$emit」を使って子コンポーネントのデータを親コンポーネントに送ります。

$emitはVueJsで定義されているイベントの内の1つで、主にイベントのトリガーを送ることができます。

第一引数にイベント名、第二引数に送りたいデータなどをセットします。

今回のコードでも、「send_data_from_another_form」というのをトリガーにして、親コンポーネントにデータを送っています。

まとめ

今回は、親コンポーネントのデータを子コンポーネントに渡す方法について紹介しました。

もう一度紹介すると、親コンポーネント内で渡したいデータを「:data=”渡したいデータ”」のように定義。

子コンポーネント内で「props[‘data’]」のように定義してから、親コンポーネントの値を使うという流れでした。

また、子コンポーネントのデータを親コンポーネントに渡す場合は「$emit」を使って、親コンポーネントにイベントを送って、処理をするという流れになります。

今回の記事が僕と同じように、親コンポーネントと子コンポーネントでデータのやり取りをする方法を探している方のお役に立てたら嬉しいです。

この記事を書いた人

南 健太郎

1991年生まれ。都内でエンジニアをしています。
このブログでは、個人開発や日々の技術に関する情報などを発信していきます。