まとめこんにちは!ともです(@_tomo_engineer)!前回はコンポーネントを定義する方法について勉強しましたが、今回はコンポーネント間でデータを受け渡しする方法について見て行きます。参考にしたものは以下です。基礎から学ぶVue.js(書籍)Vue.js:日本語ドキュメントコンポーネントの間の関係コンポーネントの関係には『親子』または『非親子』の2つが考えられます。<comp-child></comp-child></div>ルートインスタンスを親と考えると、それに含まれたコンポーネントは子だと考える事ができます。非親子の場合<comp-friend1></comp-friend1><comp-friend2></comp-friend2>また同じ階層のコンポーネントは非親子の関係にあると考える事ができます。スコープ親子間or非親子間において、thisでデータを参照する事ができません。これはスコープによるものです。他の機能に影響を与えない様にコンポーネントという単位で完結しているのです。どの様にしてコンポーネント間でデータ通信を行うのでしょうか。データの受け渡し親子間のデータの受け渡し方法は2つあります。上図の流れで親子間のデータを受け渡しします。親→子にデータを渡す場合は、属性で渡し、propsで受け取る子→親にデータを渡す場合は、$emitで渡し、onで受け取る親から子へはデータを橋渡しするだけで良いですが、子から親へはイベントを発生させて受け渡しを行う必要があります。それぞれについて見て行きます。親から子へは、属性とpropsがキーワードでした。次の様に親から子へデータを渡します。val="Bへのデータ"></my-component></div>親から子へは属性で渡します。valという属性を定義し上記の様に格納します。この属性名は任意です。子が受け取る(props)子は親からのデータをpropsというオプションを介して受け取ります。子のコンポーネントを次の様に定義しました。['val'],}propsオプションに親から子へデータを渡す際の属性名(今回の場合はval)と同じものを指定しています(props:[‘val’])。あとはデータと同様に{{val}}の様にして使用できます。描画結果としては次の様になります。<p>Aへのデータ</p><p>Bへのデータ</p>親のデータを子へ与える(v-bind)上記の場合はテキストを親から子に渡しただけでした。親コンポーネントがもつデータを子コンポーネントに渡す場合はデータバインディングを利用します。親のインスタンスにparentDataというデータを持たせます。}})子コンポーネントでは次の様にデータを渡します。v-bind:val="parentData"></my-component></div>1つ目の子要素にはテキストを与え、2つ目の子要素にはv-bindを利用し親のデータ(parentData)を与えました。'hoge'}"></my-component>//オブジェクトを与える</div>親から子に配列orオブジェクトを渡す場合はv-bindで渡す必要があります。上記3つの親から子へ渡したデータは全て静的なデータではありますが、配列・オブジェクトを与える際はv-bindで渡す必要があります。以上が親か子へのデータの受け渡しです。子から親へのデータの受け渡しを見る前にpropsに関する注意点があります。propsで受け取ったデータは書き換えてはいけないpropsで受け取ったデータは親側の更新と同期しています。親から借りてきたデータですので、子コンポーネント側で勝手に書き換えてはいけません。書き換わりはしますがエラーを吐きます。“val”書き換えた値を表示したいのであれば算術プロパティを使うなり、一度子コンポーネントのデータに格納してから加工するなりする必要があります。['val'],}の様にpropsを定義した場合は型は指定されていません。次の様に型を指定して受け取る事ができます。型の指定は推奨されているので、型は指定しましょう。}}この様に書けば文字列のみが許可され、数値を受け取った場合は警告で知らせてくれます。これは問題の箇所の発見に役立ちます。String.propsでvalidationを作成するpropsが受け取るデータはしっかり定義すると良いです。下記のコードは日本語ドキュメントから拝借しました。それを生み出すための関数を返す必要があります。}}注目すべきはオブジェクトをデフォルトとする場合は、オブジェクトを返す関数とする必要があるという事です。type(型の指定)・required(必須データの指定)で不足の場合は、カスタムバリデータも準備されています。カスタムバリデータは条件を満たすかの真偽を返す関数として定義します。子から親へは、$emitとonがキーワードでした。次の様に親から子へデータを渡します。この3つについて見て行きます。v-on:child-event="parentMethod"></my-component></div>この様に子のイベント発火をフックに、親のメソッドを起動させる事ができます。2子が$emitでイベント発火を親に伝えるemitは『発する』という意味を持ち、イベントの発火を意味しています。子コンポーネントを次の様に定義しました。}}ボタンをクリックするとthis.$emit('フック名')で親にイベント発火を伝えます。今回の場合、フック名はchild-eventです。3親は子からのイベント発火を受け取り親メソッドを起動するthis.$emit('child-event')で子から親にイベントの発火を通知しv-on:child-event="parentsMethod"で親はその通知を受け取りました。これにより親のparentsMethodが起動します。次の様に親のインスタンスを定義しました。}})parentMethodが起動し、上記の様なalertを表示してみます。upのフローを確認しました。upのフローの$emitの第二引数で子から親にデータを渡します。}})$emitの第二引数に子から親に渡したいデータをセットし、親のメソッドで受け取る事ができます。upのフローさえ覚えていれば単純でした。非親子間のデータ受け渡し非親子コンポーネント間では、propsを使ってデータ通信できません。その代わり『イベントバス』を利用して通信を行います。『イベントバス』とはVueインスタンを経由して非親子のコンポーネント間で通信を行う方法です。上図の様なイメージです。コンポーネント1からコンポーネント2へイベント通知します。その際にイベントバスを経由するという構図です。次の様に2つのコンポーネントを定義しました。Vue();を作成しました。イベントバス用のVueインスタンスの$emitや$onを利用してコンポーネント間で通信を行います。機能としては、myComponent1のボタンクリックをフック($emit)に、myComponent1のデータをmyComponent2に送信しています。$emitの第二引数に送信したいデータをセットします。}}myComponent2のマウント時に、bus.$onにより非親子間のイベントの登録しておきます。bus-eventが発火したタイミングでchangeMethodメソッドを起動する様に設定しています。this.changeMethod)},changeMethodメソッドは次の様に作成しました。引数には$emitの第二引数にセットしたデータが入っています。}}これでComponent1からComponent2にデータ(今回の場合はmessage)が渡りました。まとめ今回はVue.jsのコンポーネント間の通信について進めました。非親子関係かで通信方法は違いました。まとめると以下の様になります。up)非親子間の場合は、イベントハブを経由し、$emitで発火、$onで発火を検知する頭を整理するのに苦労しましたが、まとめて見ました。この様にデータの管理は規模が大きくなるにつれて辛くなってくる事がわかります。見習いエンジニアともSIerでSEとして働いています。勉強したことを記事にまとめます。