在 Vue 的模板中,通过 v-on 指令(简写为 @)可以监听 DOM 事件,并在触发时执行对应的 JavaScript 代码。这是连接“用户交互”与“组件逻辑”的核心方式。
基础事件绑定
最常用的形式是绑定一个方法名:
<button @click="handleClick">点击我</button>
const handleClick = () => {
console.log('按钮被点击了')
}
如果需要传入参数,可以使用内联调用:
<button @click="handleDelete(item.id)">删除</button>
当需要访问原生事件对象 $event 时:
<!-- 使用 $event 显式传递 -->
<button @click="warn('表单暂未保存', $event)">提交</button>
<!-- 不传参时,处理方法默认接收事件对象作为第一个参数 -->
<input @input="handleInput" />
事件修饰符
在事件处理函数中,我们经常需要调用 event.preventDefault() 或 event.stopPropagation() 这类原生方法。Vue 提供了事件修饰符,让你直接在模板中声明这些行为,使方法更纯粹地关注数据逻辑。
| 修饰符 | 作用 |
|----------|------------------------------------|
| .stop | 阻止事件冒泡 |
| .prevent | 阻止默认行为(如表单提交、链接跳转) |
| .self | 只有当事件是从该元素本身触发时才调用(不影响子元素冒泡) |
| .capture | 使用捕获模式添加事件监听器 |
| .once | 事件只触发一次 |
| .passive | 不阻止默认行为,提升移动端滚动性能 |
典型场景示例:
- 阻止表单提交刷新页面:
<form @submit.prevent="onSubmit">
<input v-model="form.name" />
<button type="submit">保存</button>
</form>
这里不用在 onSubmit 里手动写 e.preventDefault(),代码更干净。
- 防止按钮点击事件冒泡到父容器:
<div @click="handleCardClick">
<button @click.stop="handleButtonClick">操作</button>
</div>
点击按钮只会触发 handleButtonClick,不会触发外层的 handleCardClick。
- 只响应元素自身的点击(不受子元素影响):
<div @click.self="closePanel">
<p>这是一段文本</p>
<button>关闭</button> <!-- 点击这里不会触发 closePanel -->
</div>
修饰符可以串联使用,例如:
<a @click.stop.prevent="doThat">先阻止冒泡再阻止默认行为</a>
使用 .passive 需要注意:它不能与 .prevent 一起使用,因为前者声明了“不会阻止默认行为”,两者矛盾。
按键修饰符
在处理键盘事件时,通常需要检查具体的按键,Vue 允许在 keyup、keydown、keypress 事件上直接添加按键别名修饰符,让代码更直观。
常用按键别名:
.enter.tab.delete(捕获“Delete”和“Backspace”键).esc.space.up/.down/.left/.right
<!-- 按下 Enter 键时触发搜索 -->
<input @keyup.enter="search" placeholder="输入关键词,按回车搜索" />
<!-- Esc 关闭弹窗 -->
<div v-if="show" @keyup.esc="close">弹窗内容</div>
系统修饰键:
.ctrl.alt.shift.meta(Windows 上是 ⊞ 键,Mac 上是 ⌘ Command 键)
配合按键别名可以实现组合快捷键:
<!-- Ctrl + Enter 提交表单 -->
<textarea @keyup.ctrl.enter="submitForm"></textarea>
<!-- 仅按下 Shift 并同时按下 A(注意:必须保证其他键未按下时用 .exact ) -->
<input @keyup.shift.65="onShiftA" />
.exact 修饰符
精确控制系统修饰键的组合,确保只有指定的修饰键被按下:
<!-- 仅当 Ctrl 被单独按下(无 Shift、Alt 等)时触发 -->
<button @click.ctrl.exact="onCtrlClick">Ctrl + Click</button>
<!-- 仅当没有任何系统修饰键按下时触发 -->
<button @click.exact="onPureClick">普通点击</button>
鼠标按钮修饰符
针对鼠标事件,可以限制特定的鼠标按钮:
<button @click.left="handleLeftClick">左键点击</button>
<div @contextmenu.right.prevent="showContextMenu">右键菜单区域</div>
<button @click.middle="handleMiddleClick">中键点击</button>
为什么这些修饰符实用?
- 关注点分离:业务逻辑方法不需要混入
event.stopPropagation()这类环境操作,更容易单元测试。 - 可读性:模板直接表达了“按下什么键、事件是否阻止冒泡”的意图,新手也能一眼看懂。
- 减少错误:无需手动判断
event.key === 'Enter'字符串拼写错误。
在实际开发中,合理使用修饰符能让事件处理代码量减少 30% 以上,并且让整个组件的交互逻辑更加清晰。