人人都会AI编程

事件绑定、事件修饰符、按键修饰符

更新时间:2026-07-09

在 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 | 不阻止默认行为,提升移动端滚动性能 |

典型场景示例:

  1. 阻止表单提交刷新页面:
<form @submit.prevent="onSubmit">
  <input v-model="form.name" />
  <button type="submit">保存</button>
</form>

这里不用在 onSubmit 里手动写 e.preventDefault(),代码更干净。

  1. 防止按钮点击事件冒泡到父容器:
<div @click="handleCardClick">
  <button @click.stop="handleButtonClick">操作</button>
</div>

点击按钮只会触发 handleButtonClick,不会触发外层的 handleCardClick

  1. 只响应元素自身的点击(不受子元素影响):
<div @click.self="closePanel">
  <p>这是一段文本</p>
  <button>关闭</button>  <!-- 点击这里不会触发 closePanel -->
</div>

修饰符可以串联使用,例如:

<a @click.stop.prevent="doThat">先阻止冒泡再阻止默认行为</a>

使用 .passive 需要注意:它不能与 .prevent 一起使用,因为前者声明了“不会阻止默认行为”,两者矛盾。

按键修饰符

在处理键盘事件时,通常需要检查具体的按键,Vue 允许在 keyupkeydownkeypress 事件上直接添加按键别名修饰符,让代码更直观。

常用按键别名:

  • .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>

为什么这些修饰符实用?

  1. 关注点分离:业务逻辑方法不需要混入 event.stopPropagation() 这类环境操作,更容易单元测试。
  2. 可读性:模板直接表达了“按下什么键、事件是否阻止冒泡”的意图,新手也能一眼看懂。
  3. 减少错误:无需手动判断 event.key === 'Enter' 字符串拼写错误。

在实际开发中,合理使用修饰符能让事件处理代码量减少 30% 以上,并且让整个组件的交互逻辑更加清晰。