概要

emitを使って孫コンポーネントから親コンポーネントにデータを渡していきたいことがよくある。これまでは恥ずかしながら、下記のようにしてデータの受け渡し、イベント伝播を行っていた。

※ マークダウンの都合上ファイル拡張子をjsにしている

grandchild.js

// template
<Button @update="update">

// script
update(value) {
    this.$emit('update', value);
}

child.js

<Button @update="$emit('update')">

// script
update(value) {
    this.$emit('update', value);
}

parent.js

<Button @update="update()">

// script
update(value) {
  console.log(value)
}

まだコンポーネントが三つだからいいものの、これが4つ5つ…100個とかになるとかなりめんどくさいことになると気づいた。(ない)
これをなんとかして楽にする方法を考えたときに素晴らしい方法に出会うワイ。

$listener

ここで出てくるのが$listener。
これをコンポーネントとコンポーネントの間のコンポーネント(この場合はchild.js)で使うとイベントをscriptに登録する手間が省ける!!
これにより可読性もかなり上がること間違いなし

grandchild.js

// template
<Button @update="update">

// script
update(value) {
    this.$emit('update', value);
}

child.js

<Button @update="$listeners['update']">

// script
// ここが不要になる
// update(value) {
//  this.$emit('update', value);
// }

parent.js

<Button @update="update()">

// script
update(value) {
  console.log(value)
}

書き方としては
当コンポーネントの子コンポーネントで登録されたイベント名(今回はupdate)をupdate()としていたものの代わりに$listener[‘update’]とするだけでよい

@update="$listeners['update']"

元記事はこちら

【vue, nuxt】$listenerでデータ受け渡しを高速でおこなう
著者:
@yutoun