LoginSignup
1
1

More than 1 year has passed since last update.

Vue3でコンポーネントを作るときは、ネイティブイベントをいちいちemitしなくて良い。

Posted at

Nuxt3もRC版になったということで、勉強も兼ねて自分のWebサイトを作っている途中に遭遇した問題(その2)について。

環境

node.js v18.13.0
Typescript v4.7.4
Nuxt v3.0.0-rc.14
TailwindCSS v3.2.4
vue-gtag-next v1.14.0
※Vueは3.0系(ここ大事)
開発環境はWSL(Debian)だったりChromeOS(Crostini)だったり色々。

発端

ボタンだけのコンポーネントを作った。

せっかくTailwindCSSやVueを使っているのだから、要素単位でコンポーネントを作って使いまわそうと考え早速ボタンを作った。

AppBtn.vue
<template>
  <button :disabled="props.disabled" @click="$emit(`click`)">
    <slot />
  </button>
</template>

コンポーネント内でclickイベントが発火したら、親コンポーネントにイベントをemitする割とよくあるコンポーネント。
早速組み込んで動作確認してみると以下の症状が出た。

症状

clickが2度発火する。

親コンポーネントでボタンコンポーネントをクリックしたらconsole.log()で"click"と表示してみると、何故か2回Clickと表示される。
image.png
ちなみにVueDevToolではイベントは1回だけ発火している事になっている。
image.png
外部APIを叩くときなど非同期処理を実行するようなときには割と面倒なことが起きそうなので、できれば解決したいところ。

stop()を使っても効果なし

調べてみると「stopつけろ」という情報が出てきた。Vueのイベント修飾子の一つで、イベントの伝播を止める事ができる。

  <button :disabled="props.disabled" @click.stop="$emit(`click`)">
    <slot />
  </button>

しかし効果なし。

原因

拙い英語力で色々調べていると、1周回って日本語の情報が出てきた。曰く「Vue3はネイティブイベントをフォールスルーしてくれる」らしい。

解決策

emitを消して何も書かない。

  <button :disabled="props.disabled">
    <slot />
  </button>

不安だったが実際console上でも1回しか表示されていないのでこれが正解らしい。
image.png
そういえばVue3ではV-modelのイベントが"update:modelValue"に変わったが、この辺の変更と関係があるのかもしれない。

参考資料

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1