今回はVue.jsにおける、propsと$emitの使い方についてできるだけ噛み砕いてわかりやすく解説していきます。
Vue.jsの中でも初めは分かりにくい機能なので、必要な知識を順番にみていきます。
それでは、やっていきましょう。
Vue.jsのprops、$emitを知る前に
Vue.jsにおけるprops、$emitについて見ていく前に、コンポーネントの知識やコンポーネント間の親子関係について確認しておきましょう。
前提としてのコンポーネントの知識
Vue.jsではコンポーネントと呼ばれるHTML&CSS、Javascriptがセットになった一つの部品のようなものでページ上のコンテンツを分けて管理しています。
コンポーネントはそれぞれスコープを持っているため影響を及ぶ範囲が決まっています。
普通にコンポーネント内で定義したdataやmethodsにアクセスするには、下のコードの様にthisを使うことでアクセスできますね。
this.item
this.openModal()
この様に同じコンポーネント内のデータやメソッドには直接アクセスすることができますね。
しかし、スコープが設定されているため他のコンポーネントのデータやメソッドに直接アクセスすることはできません。
そこで使用されるのが、親子コンポーネント間でデータやメソッドのやり取りをするために使うのが、propsと$emitを使ったカスタムイベントというものです。
まずはコンポーネントの親子関係について確認しましょう。
コンポーネント同士の関係の理解(親子コンポーネント)
以下のコードのように、あるコンポーネント'compA'のなかで別のコンポーネント'compB'が使われているとします。
<template>
<div>
<comp-b />
</div>
</template>
<script>
import compB from '~/components/compB.vue'
export default {
components: {
compB
}
}
</script>
この場合compAが親コンポーネント、compBが子コンポーネントになります。
そのコンポーネントを使っている方が親、使われるコンポーネントが子である、という関係ですね。
これがコンポーネント間の親子関係という概念です。
しかし先程確認したように、親子関係にあるコンポーネント間でデータをやり取りすることができません。
このような問題を解決し、親子関係にあるコンポーネント同士で情報をやりとりするために使うのが、propsと$emitです。
では実際にどんな場面でpropsと$emitを使う場面を見ていきましょう。
propsの使い方
propsはプロパティ(property)の略で、主に親コンポーネントから子コンポーネントに値を渡す際に使用します。
具体例を見てみましょう。親コンポーネントに当たるcompAの中でmodalという子コンポーネントを使用することを考えます。
<template>
<div>
<modal v-bind:val="postItem"></modal>
</div>
</template>
<script>
import Modal from '~/components/Modal.vue'
export default {
components: {
Modal
},
data () {
return {
postItem: " "
}
}
}
</script>
<template>
<div id="overlay">
<div id="content">
<p>{{ val }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'Modal',
props: ['val'],
}
</script>
何を行っているのか、順番に見ていきましょう。
①まず親コンポーネント'compA'のテンプレート内で、modalの属性にv-bind:valとして変数を代入しています。(:valの部分はどんな文字列でもOKです。)
②valに代入された値を子コンポーネントである'Modal'で使うためにprops: ['val']として値を受け取っています。
つまり、基本の考え方は親コンポーネントからv-bindで値を渡す、渡された値を子コンポーネントでpropsで受け取るという流れです。
この流れさえ抑えておけば、難しく考える必要はありません。
次は$emitの使い方を確認します。
$emitの使い方
emitは英語で「放つ」という意味で、その名前の通り子から親へイベントを放つ役割を持っています。
先程の子コンポーネントModal.vueに閉じるためのボタンを追加しました。
親であるcompA.vueにはモーダルを閉じるためのメソッドを追加しました。
<template>
<div id="overlay">
<div id="content">
<p>{{ val }}</p>
<button v-on:click="$emit('close')">閉じる</button>
</div>
</div>
</template>
<script>
export default {
name: 'Modal',
props: ['val'],
}
</script>
<template>
<div>
<modal v-bind:val="postItem" v-on:close="closeModal"></modal>
</div>
</template>
<script>
import Modal from '~/components/Modal.vue'
export default {
components: {
Modal
},
data () {
return {
showContent: false,
postItem: " "
}
},
methods: {
closeModal() {
this.showContent = false
}
}
}
</script>
これも順番に確認していきます。
①子コンポーネントModal.vueでボタンを押した時に、$emit(イベント名)で値を送信しています。(イベント名は好きなものでOKです。今回は$emit('close')としています。)
②親コンポーネントcompAではv-on:イベント名でそのイベントが起きたことを検知してcloseModalメソッドを発火させています。
通常のVueのイベントとしてcloseイベントというものは存在しませんが、$emitを使うことでカスタムイベントとして自分でイベントを放出(emit)しているわけですね。
結果として子コンポーネントから親コンポーネント内で定義されたメソッドにアクセスすることができました。
最後に
最後にpropsと$emitの役割のおさらいです。
他にも、引数を指定してemitを使ったり、propsとemitをかけ合わせて複雑な処理を行うことも可能です。
今回は基本的な使い方を解説したので、応用的な使い方など興味のある方は調べてみてください。。
まだ曖昧な知識がある方やこれから学習を始める方は以下の記事を参考にしてみてください。