Vue3 事件处理
按钮点击、表单提交、键盘输入……页面的所有交互都靠事件驱动。
Vue 用 v-on(简写 @)绑定事件,写法比原生 addEventListener 干净,还自带一套修饰符省去模板代码。
基础绑定
@事件名="处理函数",事件触发时执行对应逻辑:
<script setup>
import { ref } from 'vue'
const count = ref(0)
const add = (n = 1) => {
count.value += n
}
</script>
<template>
<p>点击数:{{ count }}</p>
<!-- 直接调用方法 -->
<button @click="add">+1</button>
<!-- 内联写法,传参数 -->
<button @click="add(5)">+5</button>
<!-- 内联表达式(最简单) -->
<button @click="count++">直接加</button>
</template>
三种写法都支持:
| 写法 | 示例 | 使用场景 |
|---|---|---|
| 方法处理器 | @click="add" |
逻辑较多时 |
| 内联 + 传参 | @click="add(5)" |
需要传参数 |
| 内联表达式 | @click="count++" |
一句话就能搞定 |
事件对象 $event
处理函数里常常需要拿事件对象(获取输入框值、阻止默认行为等)。
最省事的写法是不传参,@submit="submit" 时,Vue 会把事件对象自动作为第一个参数传进去,所以 submit 的第一个形参 e 就直接是事件对象:
<script setup>
const submit = (e) => {
e.preventDefault() // 阻止表单默认刷新
console.log(e.target.value)
}
</script>
<template>
<form @submit="submit">
<input placeholder="随便输入点什么" />
<button type="submit">提交</button>
</form>
</template>
内联写法里要传事件对象,就得手动用特殊变量 $event:
<button @click="add(5, $event)">加 5 并看事件</button>
$event 的位置随你安排,但 JS 形参的顺序要和模板里一致:
<button @click="add(5, $event)">加 5 并看事件</button>
<button @click="add2($event, 5)">事件在前也可以</button>
const add = (num, e) => { // e 收到事件对象
console.log(num, e.target)
}
const add2 = (e, num) => { // 顺序和模板里保持一致
console.log(e.target, num)
}
修饰符
修饰符用 . 跟在事件名后面,用来调整事件的默认行为,是 Vue 最省心的部分。
修饰符分两类:
- 事件修饰符:调整”事件怎么跑”
- 按键修饰符:限定”按了哪个键才触发”
事件修饰符
| 修饰符 | 作用 | 示例 |
|---|---|---|
.stop |
阻止事件冒泡 | @click.stop |
.prevent |
阻止默认行为 | @submit.prevent |
.self |
只当点击元素自身时触发 | @click.self |
.once |
只触发一次 | @click.once |
.capture |
用捕获阶段(先父后子) | @click.capture |
.left/.right/.middle |
指定鼠标按键 | @click.middle |
修饰符可以连写:@click.stop.prevent 同时阻止冒泡和默认行为。
按键修饰符
按键修饰符限定触发条件与”键”有关,又分两种:键盘键名(按到指定键才触发)和系统修饰键(必须同时按住):
| 修饰符 | 作用 | 示例 |
|---|---|---|
.enter 等 |
键盘键名,按键匹配才触发 | @keyup.enter |
.ctrl 等 |
系统修饰键必须同时按下 | @click.ctrl |
几个高频例子:
<!-- 点击子元素不连带到父级 -->
<div @click="onDivClick">
<button @click.stop="onBtnClick">点我</button>
</div>
<!-- 表单提交阻止刷新页面,是最常见的 -->
<form @submit.prevent="submitForm">…</form>
<!-- 鼠标按下时阻止默认行为:不选中文本、不触发原生拖拽,常用于自定义拖拽 -->
<div @mousedown.prevent="onDrag">拖我</div>
<!-- 按回车才触发搜索 -->
<input @keyup.enter="search" />
<!-- 长按 Ctrl 再点击才生效 -->
<button @click.ctrl="toggle">Ctrl+点击</button>
速查卡片
| 需求 | 写法 |
|---|---|
| 普通点击 | @click="fn" |
| 传参 + 事件对象 | @click="fn(arg, $event)" |
| 阻止冒泡 | @click.stop |
| 阻止默认行为 | @submit.prevent |
| 键盘触发 | @keyup.enter="search" |
| 只触发一次 | @click.once |
| 组合修饰符 | @keyup.ctrl.enter、@click.stop.prevent |