$emitとは
通常は子→親には何もできません。
$emitを使えば子自身のイベントや
値を親に渡せます🌟
値に関してはvuexで管理しても⭕️
ただシンプルな物なら
わざわざvuex使う必要もないし…
って時とかに便利です✨
ちなにみ親→子ならpropsが⭕️
おすすめ記事
$emitでモーダルの開閉をしています。
こちらができたら
queryでのModal管理も
ぜひチャレンジしてください✨💪
書き方
@clickとセットで使用します🌟
書き方は2種類
メソッド記法
@click="methods名"
this.$emit('イベント名', 第二引数)
インライン記法
@click="$emit('イベント名', 第二引数)"
簡単な使い方
buttonを押すとalertが出ます⏰
子のbuttonを親で検知し、
親でalertの出るmethodsを発火させます。
メソッド記法ver.
解説
$emit('welcome')
子のイベント@clickを
親に検知してもらうための$emit
イベント名をwelcomeと名付けています。
@welcome
親で先ほどのイベントwelcomeを受け取って
sayHiメソッドを発火させています💡
コード
) components
methods内で$emitを
使用する場合はthisが必要です💡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<template> <button @click="welcome" > click! </button> </template> <script> export default { methods: { welcome () { this.$emit('welcome') }, }, } </script> |
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<template> <div class="page"> <ButtonAlert @welcome="sayHi" /> </div> </template> <script> import ButtonAlert from '~/components/ButtonAlert.vue' export default { components: { ButtonAlert }, methods: { sayHi () { alert('Hi!') }, }, } </script> |
インライン記法ver.
コード
) components
1 2 3 4 5 6 7 |
<template> <button @click="$emit('welcome')" > click! </button> </template> |
) pages
変更なし
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<template> <div class="page"> <ButtonAlert @welcome="sayHi" /> </div> </template> <script> import ButtonAlert from '~/components/ButtonAlert.vue' export default { components: { ButtonAlert }, methods: { sayHi () { alert('Hi!') }, }, } </script> |
第二引数の使い方
ランダムな値を渡す
簡単な使い方と似ていますが、
今度はalertでランダムに
コメントが出てきます!
No, Yes, Yes, Yes, Maybeと出ていますね🤡
解説
this.possibleAdvice.length
3つのデータが入っているので3
Math.random()
0以上1未満の擬似乱数を返します。
0.99999
2.99999
Math.floor()
引数として与えた数以下の
最大の整数を返します。
Math.random() * this.possibleAdvice.length
最大で0.999... * 3 = 2.999...
Math.floor(2.999...)
このうちの整数は 0, 1, 2 の3つ
この整数に応じてpossibleAdvice内の
何番目の文字列が
表示されるかが決まります🌟
this.$emit('give-advice', this.possibleAdvice[randomAdviceIndex])
give-adviceというイベント名を渡します。
this.this.possibleAdvice[randomAdviceIndex]
ランダムで生成された整数が0なら
配列0番目の'Yes'を親に渡して表示✨👀
コード
) components
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<template> <button @click="giveAdvice" > click! </button> </template> <script> export default { data () { return { possibleAdvice: ['Yes', 'No', 'Maybe'] } }, methods: { giveAdvice () { let randomAdviceIndex = Math.floor(Math.random() * this.possibleAdvice.length) this.$emit('give-advice', this.possibleAdvice[randomAdviceIndex]) }, }, } </script> |
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<template> <div class="page"> <ButtonAdvice @give-advice="showAdvice" /> </div> </template> <script> import ButtonAdvice from '~/components/ButtonAdvice.vue' export default { components: { ButtonAdvice }, methods: { showAdvice: function (advice) { alert(advice) }, }, } </script> |
第二引数でオブジェクトを渡す
自身が持つデータを
objectで渡すこともできます🌟
this.$emit('submit', { form: email });
実用的な例
解説
this.$emit('submit', this.form)
this.formがv-modelでバインドされている
data内のformオブジェクトです。
つまり…
this.$emit('submit', { form: 'text@gmail.com' }, { form: 'Password-1'})
コード
孫 < 子 < 親の順で記載しています✍️
) components
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<template> <input v-bind="$attrs" :placeholder="placeholder" class="input input-default" @input="$emit('input', $event.target.value)" > </template> <script> export default { props: { placeholder: { type: String, default: '', required: false, }, }, } </script> <style lang="scss" scoped> .input-default { display: block; min-height: 45px; width: 100%; padding: 0 24px; border: 1px solid #e5e5e5; border-radius: 4px; } </style> |
) components
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<template> <form class="form form-login" @submit.prevent="submit" > <InputDefault v-model="form.email" placeholder="media@alizlab.com" type="email" required class="input input-email" > メールアドレス </InputDefault> <InputDefault v-model="form.password" type="password" required class="input input-password" > パスワード </InputDefault> <button type="submit"> login </button> </form> </template> <script> import InputDefault from '~/components/InputDefault.vue' export default { components: { InputDefault }, data () { return { form: { email: '', password: '', }, } }, methods: { submit () { this.$emit('submit', this.form) console.log(this.form) }, }, } </script> <style lang="scss" scoped> .form { > .input { margin-top: 8px; &:first-child { margin-top: 0; } } > .button { margin-top: 8px; } } </style> |
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<template> <div class="page"> <FormItemInput /> </div> </template> <script> import FormItemInput from '~/components/FormItemInput.vue' export default { components: { FormItemInput }, data () { return { } }, } </script> <style lang="scss" scoped> .page { padding: 20px; } </style> |
まとめ
- $emitは子から親にイベントと値を通知するもの
- 第一引数に必ずイベント名
- 第二引数で配列やオブジェクトも渡せる