Vue.jsはwebページを部品単位で構築することによって開発を支えるJavaScriptのフレームワークです。
Vue.js
Vue.jsには単一ファイルコンポーネントという仕組みがあります。これは次のコードの様にあるwebページの部品のHTML、JavaScript、CSSを一ファイルにまとめる仕組みです。
<template> <p>{{ greeting }} World!</p> </template> <script> module.exports = { data: function () { return { greeting: 'Hello' } } } </script> <style scoped> p { font-size: 2em; text-align: center; } </style>
単一ファイルコンポーネント — Vue.js
単一ファイルコンポーネントを用いるとDOMツリーならぬコンポーネントツリーともいうべき構造のコードを記述することになります。下図はあるページのコンポーネントの階層構造です。まとめ役のmain-template、その下に検索ボックスのsearch-box-templateと各モーダル、それぞれに入力欄のform-group-row-inputが連なっています。
これはまだシンプルに保ててますが、モノによってはもっと深い構造なることもあります。
離れた場所にある異なるメニュー内に共通アクションのボタンをつけるなど、異なるコンポーネント内で定義されているイベントを発火したい時があります。そういった時は$emitで親のイベントを発火することができます。
API — Vue.js#vm-emit
サンプルコードなどでもよく現れ、よく使う形はmethod内部での$emitです。次の様に子ファイルの内部で$emit(‘イベント名’,引数)とすると、親ファイル中でhoge-eventが動き、$emitで渡された引数が格納された$event付きのhogeEventAction()が動作します。
// 親ファイル <first-template @hoge-event="hogeEventAction($event)" /> // 子ファイル method{ fuga(){ // 何か色々処理 this.$emit('hoge-event', 'hogehoge'); } }
これがよくある書き方ですが孫の様な直下よりも下にあるコンポーネントから親のイベントを発火する際には冗長です。
// 親ファイル <first-template @hoge-event="hogeEventAction($event)" /> // 子ファイル <second-template @hoge-event="hogeEventAction($event)" /> // ---省略--- method{ hogeEventAction(argv){ this.$emit('hoge-event', argv); } } // 孫ファイル method{ fuga(){ this.$emit('hoge-event', 'hogehoge'); } }
イベントの定義時にはイベントに対応する関数を記述するのがよくあるパターンですが、この部分はワンライナーならば何でも入れられます。このため中間になるコンポーネントには次の子ファイルの様に、親のイベントを発火する親と同名のイベントを定義すると簡潔なコードになります。
// 親ファイル <first-template @hoge-event="hogeEventAction($event)" /> // 子ファイル <second-template @hoge-event="$emit('hoge-event', $event)" /> // 孫ファイル method{ fuga(){ this.$emit('hoge-event', 'hogehoge'); } }
子ファイルの内部を汚さずに孫から親のイベントを発火できました。