【Vue】12 Vue技术—— Vue 事件修饰符详解:掌握事件处理的高级技巧

文章目录


前言

在 Vue.js 开发中,事件处理是构建交互式用户界面的核心。除了基础的事件绑定(如 @click="handler"),Vue 还提供了一套强大的事件修饰符(Event Modifiers) ,让我们能以声明式的方式更优雅地控制事件行为,而无需在方法内部编写繁琐的 DOM 操作逻辑(如 event.preventDefault()event.stopPropagation())。

本文将结合一个完整的示例,深入讲解 Vue 中六大常用事件修饰符:.prevent.stop.once.capture.self.passive,帮助你全面掌握它们的使用场景与原理。


示例代码结构概览

我们先来看一下示例的整体结构:

html 复制代码
<div id="root">
  <h2>欢迎来到{{name}}学习</h2>
  
  <!-- 各种事件修饰符的使用示例 -->
  <a href="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 实例定义了 showInfoshowMsg 等方法用于演示效果。


1. .prevent:阻止默认行为

作用

阻止元素的默认行为 。常用于 <a> 标签、表单提交等场景。

示例分析

html 复制代码
<a href="http://baidu.com" @click.prevent="showInfo">点我提示信息</a>
  • 正常情况下,点击链接会跳转到百度。
  • 加上 .prevent 后,event.preventDefault() 被自动调用,阻止跳转 ,只执行 showInfo 方法弹出提示。

等价于 :在方法中手动写 e.preventDefault()


2. .stop:阻止事件冒泡

作用

阻止事件向父级元素冒泡(Bubble)

示例分析

html 复制代码
<div class="demo1" @click="showInfo">
  <button @click.stop="showInfo">点我提示信息</button>
</div>
  • 点击按钮时:
    • 按钮自身的 @click.stop 触发 showInfo
    • 但由于 .stop 的存在,事件不会冒泡到外层 div ,所以 div 的点击事件不会触发
  • 若去掉 .stop,点击按钮会连续弹出两次提示(一次来自 button,一次来自 div)。

📌 应用场景:避免嵌套可点击区域时的重复触发。


3. .once:事件只触发一次

作用

让事件处理器仅执行一次,之后自动移除监听器。

示例分析

html 复制代码
<button @click.once="showInfo">点我提示信息</button>
  • 第一次点击:弹出"同学你好!"
  • 第二次及以后点击:无反应,因为监听器已被移除。

⚠️ 注意:.once 是 Vue 的特殊修饰符,不是原生 DOM API,但效果类似 addEventListener(..., { once: true })


4. .capture:使用事件捕获模式

作用

捕获阶段(而非默认的冒泡阶段)触发事件处理器。

事件流回顾

DOM 事件流分为三个阶段:

  1. 捕获阶段(从 window 到目标元素)
  2. 目标阶段
  3. 冒泡阶段(从目标元素回传到 window)

默认 Vue 事件监听处于冒泡阶段.capture 强制改为捕获阶段

示例分析

html 复制代码
<div class="box1" @click.capture="showMsg(1)">
  div1
  <div class="box2" @click="showMsg(2)">
    div2
  </div>
</div>
  • 点击 inner div(div2)时:
    • 先触发 外层 div1 的 @click.capture → 弹出 "同学你好!1"
    • 再触发 内层 div2 的 @click → 弹出 "同学你好!2"

🔁 若都用默认冒泡,则顺序相反:先 2,后 1。


5. .self:仅当事件由自身触发时才响应

作用

只有当 event.target 等于当前绑定元素本身时,才触发回调。

示例分析

html 复制代码
<div class="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

🎯 与 .stop 区别:.self 不阻止冒泡,只是过滤触发条件


6. .passive:立即执行默认行为,不等待回调

作用

告诉浏览器:不要等待事件处理函数执行完,立即执行默认行为(如滚动、缩放)。

背景

某些事件(如 touchmovewheel)如果处理函数耗时较长,会导致页面卡顿。使用 .passive 可提升滚动流畅度。

示例分析

html 复制代码
<ul @wheel.passive="demo1" class="list">...</ul>
  • demo1 方法包含一个耗时循环(打印 10000 次):

    js 复制代码
    demo1(){
      for(let i = 0; i < 10000; i++) console.log('#')
      console.log('累坏了')
    }
  • 由于 .passive滚轮操作会立即生效(列表可流畅滚动),而不会被 JS 阻塞。

  • 若去掉 .passive,滚动会明显卡顿,直到 demo1 执行完毕。

⚠️ 限制:不能与 .prevent 同时使用,因为 passive 模式下无法取消默认行为。


完整代码

css 复制代码
<!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 = new Vue({
                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 声明式编程的魅力所在。

相关推荐
摘星编程2 小时前
在OpenHarmony上用React Native实现AnimatedValue补间动画
javascript·react native·react.js
摘星编程2 小时前
React Native鸿蒙版:AnimatedXY双轴动画完整代码
javascript·react native·react.js
艾斯特_2 小时前
Echarts常用配置项及解释
前端·javascript·echarts
m0_502724952 小时前
飞书真机调试
开发语言·前端·javascript
我只会写Bug啊3 小时前
复制可用!纯前端基于 Geolocation API 实现经纬度获取与地图可视化
前端·高德地图·地图·百度地图·经纬度
刘一说3 小时前
Vue3 模块语法革命:移除过滤器(Filters)的深度解析与迁移指南
前端·vue.js·js
lkbhua莱克瓦244 小时前
JavaScript核心语法
开发语言·前端·javascript·笔记·html·ecmascript·javaweb
Trae1ounG4 小时前
这是什么dom
前端·javascript·vue.js
比老马还六4 小时前
Bipes项目二次开发/扩展积木功能(八)
前端·javascript