文章目录
- 前言
- 示例代码结构概览
- 1. `.prevent`:阻止默认行为
- 作用
- 示例分析
- 2. `.stop`:阻止事件冒泡
- 作用
- 示例分析
- 3. `.once`:事件只触发一次
- 作用
- 示例分析
- 4. `.capture`:使用事件捕获模式
- 作用
- 事件流回顾
- 示例分析
- 5. `.self`:仅当事件由自身触发时才响应
- 作用
- 示例分析
- 6. `.passive`:立即执行默认行为,不等待回调
- 作用
- 背景
- 示例分析
- 完整代码
- 总结:事件修饰符速查表
- 结语
前言
在 Vue.js 开发中,事件处理是构建交互式用户界面的核心。除了基础的事件绑定(如@click="handler"),Vue 还提供了一套强大的事件修饰符(Event Modifiers),让我们能以声明式的方式更优雅地控制事件行为,而无需在方法内部编写繁琐的 DOM 操作逻辑(如event.preventDefault()或event.stopPropagation())。
本文将结合一个完整的示例,深入讲解 Vue 中六大常用事件修饰符:.prevent、.stop、.once、.capture、.self和.passive,帮助你全面掌握它们的使用场景与原理。
示例代码结构概览
我们先来看一下示例的整体结构:
<divid="root"><h2>欢迎来到{{name}}学习</h2><!-- 各种事件修饰符的使用示例 --><ahref="http://baidu.com"@click.prevent="showInfo">...</a><div@click="showInfo"><button@click.stop="showInfo">...</button></div><button@click.once="showInfo">...</button><div@click.capture="showMsg(1)">...</div><div@click.self="showInfo"><button>...</button></div><ul@scroll="demo"class="list">...</ul><ul@wheel.passive="demo1"class="list">...</ul></div>对应的 Vue 实例定义了showInfo、showMsg等方法用于演示效果。
1..prevent:阻止默认行为
作用
阻止元素的默认行为。常用于<a>标签、表单提交等场景。
示例分析
<ahref="http://baidu.com"@click.prevent="showInfo">点我提示信息</a>- 正常情况下,点击链接会跳转到百度。
- 加上
.prevent后,event.preventDefault()被自动调用,阻止跳转,只执行showInfo方法弹出提示。
✅等价于:在方法中手动写
e.preventDefault()
2..stop:阻止事件冒泡
作用
阻止事件向父级元素冒泡(Bubble)。
示例分析
<divclass="demo1"@click="showInfo"><button@click.stop="showInfo">点我提示信息</button></div>- 点击按钮时:
- 按钮自身的
@click.stop触发showInfo; - 但由于
.stop的存在,事件不会冒泡到外层 div,所以 div 的点击事件不会触发。
- 按钮自身的
- 若去掉
.stop,点击按钮会连续弹出两次提示(一次来自 button,一次来自 div)。
📌应用场景:避免嵌套可点击区域时的重复触发。
3..once:事件只触发一次
作用
让事件处理器仅执行一次,之后自动移除监听器。
示例分析
<button@click.once="showInfo">点我提示信息</button>- 第一次点击:弹出“同学你好!”
- 第二次及以后点击:无反应,因为监听器已被移除。
⚠️ 注意:
.once是 Vue 的特殊修饰符,不是原生 DOM API,但效果类似addEventListener(..., { once: true })。
4..capture:使用事件捕获模式
作用
在捕获阶段(而非默认的冒泡阶段)触发事件处理器。
事件流回顾
DOM 事件流分为三个阶段:
- 捕获阶段(从 window 到目标元素)
- 目标阶段
- 冒泡阶段(从目标元素回传到 window)
默认 Vue 事件监听处于冒泡阶段。.capture强制改为捕获阶段。
示例分析
<divclass="box1"@click.capture="showMsg(1)">div1<divclass="box2"@click="showMsg(2)">div2</div></div>- 点击 inner div(div2)时:
- 先触发外层 div1 的
@click.capture→ 弹出 “同学你好!1” - 再触发内层 div2 的
@click→ 弹出 “同学你好!2”
- 先触发外层 div1 的
🔁 若都用默认冒泡,则顺序相反:先 2,后 1。
5..self:仅当事件由自身触发时才响应
作用
只有当event.target等于当前绑定元素本身时,才触发回调。
示例分析
<divclass="demo1"@click.self="showInfo"><button@click="showInfo">点我提示信息</button></div>- 点击button:
- button 的点击事件触发(弹窗);
- 但 div 的
@click.self不触发,因为event.target是 button,不是 div。
- 点击div 的空白区域(非 button):
- div 的
@click.self会触发,因为此时event.target === div。
- div 的
🎯 与
.stop区别:.self不阻止冒泡,只是过滤触发条件。
6..passive:立即执行默认行为,不等待回调
作用
告诉浏览器:不要等待事件处理函数执行完,立即执行默认行为(如滚动、缩放)。
背景
某些事件(如touchmove、wheel)如果处理函数耗时较长,会导致页面卡顿。使用.passive可提升滚动流畅度。
示例分析
<ul@wheel.passive="demo1"class="list">...</ul>demo1方法包含一个耗时循环(打印 10000 次):demo1(){for(leti=0;i<10000;i++)console.log('#')console.log('累坏了')}- 由于
.passive,滚轮操作会立即生效(列表可流畅滚动),而不会被 JS 阻塞。 - 若去掉
.passive,滚动会明显卡顿,直到demo1执行完毕。
⚠️ 限制:不能与
.prevent同时使用,因为 passive 模式下无法取消默认行为。
完整代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>事件修饰符</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> <style> *{margin-top:20px;}.demo1{height:50px;background-color:skyblue;}.box1{padding:5px;background-color:skyblue;}.box2{padding:5px;background-color:orange;}.list{width:200px;height:200px;background-color:peru;overflow:auto;}li{height:100px;}</style> </head> <body> <!-- Vue中的事件修饰符: 1.prevent:阻止默认事件(常用); 2.stop:阻止事件冒泡(常用); 3.once:事件只触发一次(常用); 4.capture:使用事件的捕获模式; 5.self:只有event.target是当前操作的元素时才触发事件; 6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕; --> <!-- 准备好一个容器 --> <div id="root"> <h2>欢迎来到{{name}}学习</h2> <!-- 阻止默认事件(常用) --> <a href="http://baidu.com"@click.prevent="showInfo">点我提示信息</a> <!-- 阻止事件冒泡 --> <div class="demo1"@click="showInfo"> <button @click.stop="showInfo">点我提示信息</button> </div> <!-- 事件只触发一次 --> <button @click.once="showInfo">点我提示信息</button> <!-- 使用事件的捕获模式 --> <div class="box1"@click.capture="showMsg(1)"> div1 <div class="box2"@click="showMsg(2)"> div2 </div> </div> <!-- 只有event.target是当前操作的元素时才触发事件 --> <div class="demo1"@click.self="showInfo"> <button @click="showInfo">点我提示信息</button> </div> <!-- 事件的默认行为立即执行,无需等待事件回调执行完毕 --> <ul @scroll="demo"class="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <ul @wheel.passive="demo1"class="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </div> <script type="text/javascript"> Vue.config.productionTip = false // 阻止Vue在启动时产生生产提示 const vm = newVue({el:'#root', data:{name:'上高山'}, methods:{showInfo(e){// e.preventDefault()// 阻止事件的默认行为,也可以通过@click.prevent来阻止,prevent就是一个事件修饰符alert('同学你好!')},showMsg(msg){alert('同学你好!'+ msg)}, demo(){console.log('@')}, demo1(){for(let i = 0;i < 10000;i++){console.log('#')}console.log('累坏了')}}})</script> </body> </html>总结:事件修饰符速查表
| 修饰符 | 作用 | 常见场景 |
|---|---|---|
.prevent | 阻止默认行为 | 阻止链接跳转、表单提交 |
.stop | 阻止事件冒泡 | 嵌套点击区域防重复触发 |
.once | 事件只触发一次 | 初始化操作、一次性确认 |
.capture | 使用捕获阶段 | 需要先处理外层逻辑 |
.self | 仅自身触发才响应 | 精确控制事件源 |
.passive | 默认行为立即执行 | 优化滚动、触摸性能 |
💡组合使用:Vue 允许多个修饰符连用,如
@click.stop.prevent。
结语
Vue 的事件修饰符极大简化了 DOM 事件的控制逻辑,使代码更清晰、性能更优。掌握这些修饰符,不仅能写出更健壮的交互逻辑,还能避免常见的事件陷阱(如冒泡干扰、滚动卡顿等)。建议在实际项目中根据需求灵活选用,提升用户体验与开发效率。
🌟最佳实践:优先使用修饰符,而非在方法中手动调用
event.stopPropagation()或preventDefault()—— 这正是 Vue 声明式编程的魅力所在。