こんにちは、”はふぃ”です。
コンポーネントは名前付きの再利用可能な Vue インスタンスです。
https://jp.vuejs.org/v2/guide/components.html
Vue.jsではモジュールをコンポーネント化し、一つのコンポーネントの中で複数のコンポーネントを呼ぶことが多いです。
この場合に、呼んでいる方のコンポーネントを「親」、呼ばれる側のコンポーネントを「子」と言います。
< parentConponent.vue >
<template> <div> <child-component /> <child-component /> <child-component /> </div> </template> <script> import childComponent from './childComponent' export default { components: { childComponent } } </script>
< childComponent.vue >
<template> <div>{{ message }}</div> </template> <script> export default { data () { return { message: 'Hello World!' } } } </script>
この時、親子間でデータを受け渡す必要がある場合があると思いますが、親から子に渡す場合にはprops
を利用します。
プロパティ — Vue.js
https://jp.vuejs.org/v2/guide/components-props.html
では、子から親にデータを渡す際にどうするのかについていくつか方法があるので説明します。
方法
$emit
vm.$emit( eventName, […args] )
https://jp.vuejs.org/v2/api/index.html#vm-emit
$emitを利用すると子コンポーネントから親コンポーネントのメソッドを呼び、データを受け渡すことが可能です。
< parentComponent.vue >
<template> <div> <child-component @parentMethod="updateMessage" ></child-component> <!-- 'Hello World!'が表示されます --> <p>{{ message }}</p> </div> </template> <script> import childComponent from './childComponent' export default { data () { return { message: '' } }, components: { childComponent }, methods: { updateMessage (message) { this.message = message } } } </script>
< childComponent.vue >
<template> <div></div> </template> <script> export default { data () { return { message: 'Hello World!' } }, mounted () { this.$emit('parentMethod', this.message) } } </script>
$listeners
子コンポーネントから親コンポーネントへは$emit
でデータを受け渡すことが可能ですが、孫コンポーネント(子コンポーネントの子)から親コンポーネントのメソッドを呼ぶには、$emit
を2度使ってデータを孫 → 子 → 親と渡す必要があります。その際に$listeners
を利用することでより分かりやすく記述することが可能です。
< parentComponent.vue >
<template> <div> <child-component @parentMethod="updateMessage" ></child-component> <!-- 'Hello World!'が表示されます --> <p>{{ message }}</p> </div> </template> <script> import childComponent from './childComponent' export default { data () { return { message: '' } }, components: { childComponent }, methods: { updateMessage (message) { this.message = message } } } </script>
< childComponent.vue >
<template> <grand-child-component @childMethod="$listeners['parentMethod']" ></grand-child-component> </template> <script> import grandChildComponent from './grandChildComponent' export default { components: { grandChildComponent } } </script>
< grandChildComponent.vue >
<template> <div></div> </template> <script> export default { data () { return { message: 'Hello World!' } }, mounted () { this.$emit('childMethod', this.message) } } </script>
まとめ
子コンポーネントを再利用する際などに、$emit
で呼ぶ親コンポーネントのメソッドが必要なことがわからないことが多いので、コメントなど利用して明記した方がいいかもしれません。