【Vue×Vuetify】子要素のイベントを親要素に伝播しないようにする方法を解説します。

Vue.js Vuetify Web制作

【Vue×Vuetify】子要素のイベントを親要素に伝播しないようにする方法を解説します。

なやむくん
子要素のイベントだけを発火させたいのに親要素のイベントも発火してしまう…。
なやむさん
子要素のイベントだけ発火できるようにしたい…。

などの疑問や悩みを解決してまいります。

親要素にもイベント処理を指定しており、子要素にもイベント処理を指定して各イベントを個別に実行したいのに、両方ともイベント処理が実行されてしまう…そんな現象に悩まれていませんか?

今回は、この問題の原因と解決方法について解説していきます。

子要素のイベントと親要素のイベントが同時に起きる現象例

実際にどのような問題かを確認してみましょう。

<template>
  <v-container>
    <v-expansion-panels multiple>
      <v-expansion-panel>
        <v-expansion-panel-title>
          <p>タイトルが入ります</p>
          <v-select
            :items="selectItems"
            density="compact"
            label="選択してください"
            class="px-4"
          ></v-select
        ></v-expansion-panel-title>
        <v-expansion-panel-text>
          <p>
            テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。
          </p>
        </v-expansion-panel-text>
      </v-expansion-panel>
    </v-expansion-panels>
  </v-container>
</template>
<script setup land="ts">
const selectItems = ["選択肢1", "選択肢2", "選択肢3", "選択肢4"];
</script>

上記は、Vuetifyのコンポーネントタグを使用してアコーディオン機能の中にセレクトボックスを追加しています。

本来やりたいことはセレクトボックスをクリックすると選択ボックスだけが表示される、アコーディオン領域をクリックすると開閉処理だけが実行されることなのですが、セレクトボックスをクリックするとなぜか選択ボックスの表示と開閉処理も同時に行われてしまいます。

このようにパネル開閉と選択ボックスの表示が同時に行われてしまっているのが分かると思います。

みつた
イケてないですね…。

原因:バブリング

この原因はイベントのバブリングという現象にあります。

バブリングとは、子要素のイベント発生が親要素にも順に伝播する現象のことを言います。

つまり今回起きている現象として、子要素のv-selectの選択ボックス表示イベントが親要素のv-expansion-panelのパネル開閉イベントにも伝播してしまい、結果的に両方のイベントが発生してしまうということになります。

みつた
上記の理由から、親要素のパネル部分だけをクリックしてもパネル開閉のイベントしか発生しません。

解決方法:@click.stop

解決方法は子要素のv-selectに対して@click.stopのイベント修飾子を追加します。

<template>
  <v-container>
    <v-expansion-panels multiple>
      <v-expansion-panel>
        <v-expansion-panel-title>
          <p>タイトルが入ります</p>
          <v-select
            :items="selectItems"
            density="compact"
            label="選択してください"
            class="px-4"
            @click.stop // 追加
          ></v-select
        ></v-expansion-panel-title>
        <v-expansion-panel-text>
          <p>
            テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。
          </p>
        </v-expansion-panel-text>
      </v-expansion-panel>
    </v-expansion-panels>
  </v-container>
</template>
<script setup land="ts">
const selectItems = ["選択肢1", "選択肢2", "選択肢3", "選択肢4"];
</script>

追加することでイベントのバブリングを防ぐことができます。

このように親要素へのイベントの伝播を防ぐことができ、同時イベント実行の現象は改善できます。

まとめ

ここまで読んでいただきありがとうございました。

本記事のまとめです。

本記事のまとめ

  • バブリングとは、子要素のイベント発生が親要素にも順に伝播する現象のこと
  • 子要素に対して@click.stopのイベント修飾子を追加することで、バブリングを防ぐことができる
  • この記事を書いた人
  • 最新記事

みつた

完全未経験&異業種から30歳の年でIT企業に転職。

Web系開発言語が好き。
どちらかというとバックエンドよりもフロントエンドが好き(現時点では…)

最近はサウナと観葉植物にハマっている。
野球が好きで一応投手。

-Vue.js, Vuetify, Web制作