| この記事の要点 |
|
基本: @click と v-on:click
Vue.js でクリックイベントを扱う最も基本的な書き方は v-on:click ディレクティブで、@ で省略できます。
<template>
<!-- 省略形 (推奨) -->
<button @click="increment">+1</button>
<!-- 正式形 -->
<button v-on:click="increment">+1</button>
<!-- インライン式 -->
<button @click="count++">+1</button>
<!-- 引数を渡す -->
<button @click="addItem('apple')">Apple</button>
<!-- $event とともに渡す -->
<button @click="addItem('apple', $event)">Apple</button>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => { count.value++; };
const addItem = (name, event) => {
console.log(name, event.target);
};
</script>
$event: ネイティブイベントオブジェクト
メソッドの引数に $event を渡すと、DOM の MouseEvent をそのまま受け取れます。
<template>
<button @click="onClick($event)">クリック</button>
<button @click="onClick">クリック (自動)</button>
</template>
<script setup>
const onClick = (e) => {
console.log(e.target); // クリックされた要素
console.log(e.clientX, e.clientY); // 座標
console.log(e.shiftKey, e.ctrlKey); // 修飾キー
e.preventDefault(); // デフォルト動作キャンセル
e.stopPropagation(); // バブリング停止
};
</script>
引数を書かずに @click="onClick" としても、第一引数に自動的に MouseEvent が渡されます。
イベント修飾子(Modifiers)
頻出のイベント処理を 修飾子で 1 行に書けます。e.preventDefault() 等を JS 側に書かずに済みます。
| 修飾子 | 動作 | 等価な JS |
|---|---|---|
.stop | イベント伝播を止める | e.stopPropagation() |
.prevent | デフォルト動作をキャンセル | e.preventDefault() |
.capture | キャプチャフェーズで処理 | addEventListener の第 3 引数 true |
.self | 自身が target のときだけ発火 | if (e.target === e.currentTarget) |
.once | 一度だけ発火 | addEventListener の {once:true} |
.passive | パッシブリスナー(スクロール最適化) | addEventListener の {passive:true} |
<!-- バブリング停止 -->
<div @click="onOuter">
<button @click.stop="onInner">押しても onOuter は呼ばれない</button>
</div>
<!-- ページ遷移を止めて Ajax 送信 -->
<form @submit.prevent="onSubmit">
<button>送信</button>
</form>
<!-- 一度だけ -->
<button @click.once="onceOnly">一度だけ反応</button>
<!-- 修飾子は連結可 -->
<a @click.stop.prevent="onLink" href="/foo">独自処理</a>
<!-- 自身がクリックされたときだけ -->
<div @click.self="onBackdrop" class="modal-backdrop">
<div class="modal-content">子要素クリックは無視される</div>
</div>
マウスボタン・キー修飾子
<!-- 左クリックのみ -->
<button @click.left="onLeft">左クリック</button>
<!-- 右クリックのみ -->
<button @click.right="onRight">右クリック</button>
<!-- 中ボタンクリック -->
<button @click.middle="onMiddle">中ボタン</button>
<!-- Ctrl + クリック -->
<button @click.ctrl="onCtrlClick">Ctrl+Click</button>
<!-- Shift + クリック(他のキーは無視) -->
<button @click.shift.exact="onShiftOnly">Shift+Click のみ</button>
Composition API でのクリック処理
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const items = ref([]);
// シンプルな関数
const increment = () => count.value++;
// 引数あり
const remove = (id) => {
items.value = items.value.filter(i => i.id !== id);
};
// async も使える
const submit = async () => {
const res = await fetch('/api/save', { method: 'POST' });
if (!res.ok) console.error('失敗');
};
</script>
<template>
<button @click="increment">{{ count }}</button>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
<button @click="remove(item.id)">削除</button>
</li>
</ul>
<button @click="submit">保存</button>
</template>
子コンポーネントから親へ: $emit
子コンポーネントでクリックが起きたとき、親に通知するには $emit(Composition API では defineEmits)を使います。
<!-- 子: MyButton.vue -->
<script setup>
const emit = defineEmits(['click', 'longpress']);
const onNativeClick = (e) => {
emit('click', { x: e.clientX, y: e.clientY });
};
</script>
<template>
<button @click="onNativeClick"><slot /></button>
</template>
<!-- 親: Parent.vue -->
<script setup>
const handleChildClick = (payload) => {
console.log('子からの payload:', payload);
};
</script>
<template>
<MyButton @click="handleChildClick">押す</MyButton>
</template>
v-on のオブジェクト構文(複数イベント)
<template>
<!-- 複数のイベントをまとめて -->
<input v-on="{
click: onClick,
focus: onFocus,
blur: onBlur,
keydown: onKey,
}" />
</template>
React onClick との比較
| 項目 | Vue.js | React |
|---|---|---|
| 記法 | @click="fn" | onClick={fn} |
| 引数渡し | @click="fn(id)" | onClick={() => fn(id)} |
| イベント取得 | $event または第一引数 | 第一引数 SyntheticEvent |
| preventDefault | @click.prevent | e.preventDefault() 手動 |
| stopPropagation | @click.stop | e.stopPropagation() 手動 |
| カスタムイベント | $emit + defineEmits | props として渡す |
よくあるトラブル
- v-for 内でクリック先が間違う →
:keyが無い / 重複している。一意キーを付ける - 子コンポーネントの @click が効かない → ルート要素が単一でない場合、attrs 継承されない。
defineEmits(['click'])+@click="$emit('click', $event)"で明示 - ボタン連打で多重送信 →
.once修飾子、またはdisabled制御
FAQ
Q: Vue 2 と Vue 3 で書き方は変わる?
A: 基本構文は同じ(@click、修飾子、$emit)。Vue 3 は Composition API(<script setup>)と defineEmits が追加されたぶん、より明示的になりました。
Q: 動的なイベント名は使える?
A: 使えます。@[eventName]="handler" のように動的引数を指定できます。Vue 2.6+ / Vue 3。
Q: addEventListener との違いは?
A: @click は内部で addEventListener を呼んでいます。コンポーネントが unmount されるとリスナーも自動解除されるので、手動 cleanup 不要。
子ページ
子ページはありません
同階層のページ
- インストール(ファイルのダウンロード)
- npmを使用したプロジェクトの作成
- for 繰り返し処理
- ifの条件分岐とtemplateを用いたグループ化
- クリック時のイベント処理(on:click)
- modelとdata フォーム入力値とDOMへの即時反映
- computed(算出プロパティ)と使い方とdataとの違い
- ライフサイクルフック(created / mounted / updated / destroyedの使い方)
- $nextTickの使い方(ライフサイクルフック)
- メソッドの定義方法
- エラー一覧
- ルーティング設定
- aリンクの貼り方と動的URLの作成
- Mixinを利用した共通処理の記述方法
- v-bindによるデータ連携
- ヘッダー/フッターの共通コンポーネント
- ナビゲーションの現在ページをハイライトする方法
- 画面サイズの取得方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09