【vue】 emitで子から親のメソッドを実行するには
emitは、子のコンポーネントから親へ情報を伝えるための手段です。主に親のメソッドを呼び出すのに利用します。カスタムイベントとも言います。
使い方
親は、子がemitするための情報を渡します。子は、その情報に合わせてemitを実行します。
<!-- 子でthis.$emit("update-value", 渡したい値);を呼ぶと、親でsetValueが呼ばれる --> <button-component @update-value="setValue"></button-component>
const app = Vue.createApp({ data() { return { value: 0 }; }, methods: { setValue(event) { this.value = event; } } }); app.component("button-component", { data() { return {}; }, methods: { update() { // 親のHTMLで設定されたメソッドを呼び出す this.$emit("update-value", Math.random()); } }, template: ` <div> <button @click="update">親の値更新!</button> </div> ` });
See the Pen vue emit by Totori (@souki202) on CodePen.
このemit
の流れはこうです。少し長いですが頑張って追っていきましょう。

- ボタンをクリックすると、
@click
に書いたメソッドが走る- 他のコンポーネントのメソッドは呼び出せません。自分のコンポーネントのものだけ呼べます
-
update
内で、this.$emit
を通して親で指定したイベントを呼ぶ- 親のHTMLで
@update-value
としたら、子ではthis.$emit("update-value", ...)
とします。 $emit
の第2引数には、伝えたい値を入れます。
- 親のHTMLで
-
@update-value
で指定したものが実行される。ここではsetValue
を指定しているので、それが呼ばれる- メソッド本体を指定すると第1引数にはイベントが入ります。このイベントは、
$emit
の第2引数に入れたものです。
- メソッド本体を指定すると第1引数にはイベントが入ります。このイベントは、
- 親にある
setValue
が走る
説明で区別しやすくするため、意図的にsetValue
とupdate-value
を分けています。
つまり、親のHTMLでemit対象とemitするための名前を指定し、子ではその名前を利用して呼び出します。
データを複数渡したい場合、連想配列にして渡す必要があります。
this.$emit("...", {hoge: 100, fuga: "foo"});
emitの宣言
コンポーネントでは、どんなemit
に対応するかを書けます。
app.component("button-component", { data() { return {} }, emits: ["update-value"], // ... });
書かなくても動作はしますが、どんなemitが欲しいのかがわかりやすくなり、エディタ上では入力補完が効くようになるため、打ち間違いなどのミスの減少にも役立ちます。
emitのバリデーション
emit
に設定したものを動作させる際には、値が正しいかのバリデーションを行うことが一応可能です。
app.component("button-component", { data() { return {} }, emits: { "update-value": function (value) { // valueが0.5未満だったらemit中断 if (value < 0.5) { return false; } return true; } }, methods: { update() { this.$emit("update-value", Math.random()); } }, template: ` <div> <button @click="update">親の値更新!</button> </div> ` });
しかし、バリデーションを行う部分でのthis
は、function、アロー関数共にコンポーネントではなくwindow
を指し、this.$emit
の戻り値も成功失敗関わらずundefined
なため、あまり役立ちません。普通に別でバリデーション用のメソッドをmethods
に入れて走らせるほうが得策です。
まとめ
emit
を使用することで、子から親に向かってメソッドを実行できます。
普通のクラス設計では、クラスの双方向参照は避けられます。vueでもemitは分かりづらい動きであり、出番は減らしたいところです。
また、emitを応用し、v-modelを使って子から親に値を送信する方法があります。
