vue中的事件修饰符.self、.capture和.passive

article/2025/10/26 5:52:14

vue中的事件修饰符有6种:

  • .stop
  • .prevent
  • .capture
  • .once
  • .self
  • .passive

.stop是stopPropagation停止冒泡,
.prevent是preventDefault阻止默认事件,
.once是点击事件将只会触发一次

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

1、.self

只在目标Dom是绑定了动作的Dom才触发
也就是说只有这个Dom绑定了这个事件,且触发的dom是这个目标dom,才会触发这个事件。**

实例:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>.self修饰符</title><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body><div id='app'><div @click="log('11')" @click.self="log('12')" style="background-color: aqua; height: 400px; width: 400px;"><div @click="log('21')" @click.self="log('22')" style="background-color: #2195de; height: 200px; width: 400px;"><div @click.prevent="log('31')" @click.self="log('32')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 100px;text-align: center;">事件修饰符探索</div></div></div></div><script>var app = new Vue({el:"#app",methods:{log(value){console.log(value)}}})</script>
</body>
</html>

可以看到有三块区域:1是最外层,2是第二层,3是最里层。
1包栝2和3,2包括3

那么我点击区域3,打印出:

先触发的是区域3中的.prevent和.self修饰符事件,然后是区域2中的点击事件,但是.self事件没有触发,最后是区域1中的点击事件,同样.self事件没有触发。因为我们的目标DOM是区域3,所以触发的是区域3中的.self。

我们注意到区域2和区域3都是在事件冒泡阶段触发的,这个一定要注意,因为跟下面要讲解的.capture有关

如果.prevent改为.stop,那么区域2和3的点击事件是不会触发的。说明区域2和区域3中的事件是在冒泡阶段触发的

那么我们点击触发区域2呢?

可以看到打印出的情况,这时区域2中的.self修饰符事件也触发了。因为我们的目标对象是区域2。

2、.capture

capture汉语意思:捕获
主要是在事件的捕获阶段触发父级元素的事件。
刚才在上面的.self的例子中我们说了目标元素的外层元素的事件是在事件冒泡阶段触发的。那如果加上.capture修饰符,就会在事件的捕获阶段触发。

实例:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>.self修饰符</title><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body><div id='app'><div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;"><div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;"><div @click.stop="log('31')" @click.self="log('32')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 100px;text-align: center;">事件修饰符探索</div></div></div></div><script>var app = new Vue({el:"#app",methods:{log(value){console.log(value)}}})</script>
</body>
</html>
我们点击区域3,可以看到 这里发现先触发了区域1和2中的事件,然后再到区域3中的事件。 说明加上.capture修饰符是在捕获阶段触发了事件。 因为设置了stop所以冒泡阶段的事件没有触发,没有打印出22,12,如果不加stop,会打印出22,12的

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

3、.passive

汉语意思:被动的,消极的;被动语态的
.passive 会告诉浏览器你不想阻止事件的默认行为
prevent 是拦截默认事件,passive是不拦截默认事件。
passive这个修饰符会执行默认方法。你们可能会问,明明默认执行为什么会设置这样一个修饰符。这就要说一下这个修饰符的本意了。

某些标签拥有自身的默认事件,如a[href="#"],button[type=“submit”] 这种标签在冒泡结束后会开始执行默认事件。注意默认事件虽然是冒泡后开始,但不会因为stop阻止事件传递而停止。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>.self修饰符</title><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body><div id='app'><div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;"><div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;"><div @click.capture.stop="log('31')" @click.self="log('32')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 50px;text-align: center;"><a @click="log('41')" href="javascript: console.log('默认事件')" style="display: block;height: 50px;width: 4oopx;background-color: red;">点击a标签</a></div></div></div></div><script>var app = new Vue({el:"#app",methods:{log(value){console.log(value)}}})</script>
</body>
</html>
点击a标签,打印的数据如下:

因为在代码中写了@click.capture.stop="log(‘31’)"这一行,所以第三次捕获后终止事件传递,没有打印41,但不会阻止默认事件。

上面的代码进行了一些改动,如下:

<div id='app'><div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;"><div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;"><div @click.capture="log('31')" @click="log('32')" @click.self="log('33')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 50px;text-align: center;"><a @click="log('41')" @click.capture="log('42')" href="javascript: console.log('默认事件')" style="display: block;height: 50px;width: 4oopx;background-color: red;">点击a标签</a></div></div></div></div>

打印结果如下:

注意一点:默认事件在冒泡事件之后执行

如果加上.passive就会发现执行顺序发生了变化。

passive的作用是事件的默认行为立即执行(不用去查看有没有阻止默认事件的行为了),而且无需等待事件回调执行完毕。

<div id='app'><div @click.capture="log('11')" @click="log('12')" @click.self="log('13')" style="background-color: aqua; height: 400px; width: 400px;"><div @click.capture="log('21')" @click="log('22')" @click.self="log('23')" style="background-color: #2195de; height: 200px; width: 400px;"><div @click.capture="log('31')" @click="log('32')" @click.self="log('33')" style="background-color: #9521de; height: 100px; width: 400px;color:#fff;line-height: 50px;text-align: center;"><a @click.passive="log('41')" @click.capture="log('42')" href="javascript: console.log('默认事件')" style="display: block;height: 50px;width: 4oopx;background-color: red;">点击a标签</a></div></div></div></div>

打印结果如下:
在这里插入图片描述
对比上面的例子,发现42比41提前打印了。

使用.passive修饰符的原因:

浏览器只有等内核线程执行到事件监听器对应的JavaScript代码时,才能知道内部是否会调用preventDefault函数来阻止事件的默认行为,所以浏览器本身是没有办法对这种场景进行优化的。这种场景下,用户的手势事件无法快速产生,会导致页面无法快速执行滑动逻辑,从而让用户感觉到页面卡顿

通俗点说就是每次事件产生,浏览器都会去查询一下是否有preventDefault阻止该次事件的默认动作。我们加上passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。

这里一般用在滚动监听,@scoll,@touchmove 。因为滚动监听过程中,移动每个像素都会产生一次事件,每次都使用内核线程查询prevent会使滑动卡顿。我们通过passive将内核线程查询跳过,可以大大提升滑动的流畅度。

注:passive和prevent冲突,不能同时绑定在一个监听器上。

最后我们来看一下修饰符的组合使用

以.prevent.self和.self.prevent为例
官网上说
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
1、prevent.self

<div @click="log(1)">区域1<a href="/#a" @click.prevent.self="log(2)">区域2<div @click="log(3)">区域3</div></a>
</div>

点击区域3,会打印出 3,1。不但阻止了log(2),还阻止了a的默认跳转。
因为点击的时候会先prevent,阻止默认事件,阻止了跳转;然后判断是否是self,因为点击到的是区域3,所以不是self,阻止了log(2)。

2、self.prevent

<div @click="log(1)">区域1<a href="/#a" @click.self.prevent="log(2)">区域2<div @click="log(3)">区域3</div></a>
</div>

点击区域3,会打印出3,1,跳转到/#a。只阻止了log(2)。

因为会先判断self,点击到区域3,self是区域3,区域2不是self,所以不会执行self事件,self事件后面紧跟着是prevent,self都不执行了,所以prevent也不会执行了,就不会执行 阻止默认事件和log(2) 。所以默认事件是可以执行的,可以跳转。
参考文章:Vue事件修饰符(二).prevent .passive


http://chatgpt.dhexx.cn/article/LvykiFDB.shtml

相关文章

FileZilla客户端连接腾讯云FTP服务器时出现“227 Entering Passive Mode”

FTP的主动模式(PORT Mode)及被动模式(Passive Mode) FTP的特殊性&#xff1a; 大多数的TCP服务是使用单个的连接&#xff0c;一般是客户向服务器的一个周知端口发起连接&#xff0c;然后使用这个连接进行通讯。但是&#xff0c;FTP协议却有所不同&#xff0c;它使用双向的多个连…

FTP Entering Extended Passive Mode

目录 原因 两种方法解决,哪个行用哪种 方法一 方法二 原因 FTP的连接建立有两种模式PORT

ftp的passive模式

昨天调试了半天的ftp passive模式&#xff0c;记录一下 今天在一台测试服务器上搭建ftp&#xff0c;折腾了许久。 主要是不了解ftp的passive模式和port模式的区别。这里记录一下。 和passive模式对应的叫做port模式&#xff0c;也叫做standard模式&#xff0c;也叫主动模式。 每…

一篇文章彻底掌握 FTP 服务器的 ACTIVE 与 PASSIVE 工作模式

1 背景 某客户现场&#xff0c;每天都会批量生成大量 CSV 文件存放到 FTP 系统&#xff0c;这些 CSV 文件需要导入到大数据平台 HIVE 数仓中做后续离线分析&#xff0c;且 HIVE 数仓中的离线分析作业目前是使用 JENKINS 来调度的。 由于这些 CSV 文件是每天都会生成&#xff0c…

passive 的事件监听器

很久以前&#xff0c;addEventListener() 的参数约定是这样的&#xff1a; addEventListener(type, listener, useCapture) 后来&#xff0c;最后一个参数&#xff0c;也就是控制监听器是在捕获阶段执行还是在冒泡阶段执行的 useCapture 参数&#xff0c;变成了可选参数&…

强化学习之Passive learning求解 (1)

在MDP系列博客中&#xff0c;我们以一个Agent在4*3网格中寻找终点最优的路径策略为例&#xff0c;论述了MDP问题的原理和求解。有了MDP讲解作为基础之后&#xff0c;我们就可以正式的切入到“强化学习”的学习中来了。强化学习的目的是通过观测到的reward来为当前环境学习一个&…

【重要!!】passive优化页面性能

在js中给dom元素添加监听事件&#xff1a; let dom1document.getElementById("box1"); function box(that){console.log(that); } dom1.addEventListener("click",function(){box(1)});一般都是这样&#xff0c;但是还是有第三个参数&#xff0c;Boolean类…

Passive Event Listener

起源 最近打开项目随便点点&#xff0c;控制台就开始报警&#xff1a; Added non-passive event listener to a scroll-blocking ‘mousewheel’ event. Consider marking event handler as ‘passive’ to make the page more responsive 可以看到警告信息是element-ui和echa…

passive的作用和原理

passived到底有什么用&#xff1f; passived主要用于优化浏览器页面滚动的性能&#xff0c;让页面滚动更顺滑~~BetterScroll&#xff1a;可能是目前最好用的移动端滚动插件 passived产生的历史时间线 addEventListener()&#xff1a;大家都是认识的&#xff0c;为dom添加触发…

Java并发编程—CompletableFuture的介绍和使用

在博主上一篇博客介绍中&#xff0c;Java并发编程—java异步Future的迭代过程_小魏快起床的博客-CSDN博客&#xff0c;这里面给大家分析了Future的使用过程和一些存在的问题&#xff0c;那么针对里面出现的阻塞问题&#xff0c;博主将在这一篇文章给大家介绍清楚 &#x1f34f…

Java8 CompletableFuture runAsync等使用学习总结 submit() execute()等

一般的 Executors 的 execute以及submit 并发包下 Executors 创建的线程存在 一个 execute()&#xff0c;以及三个 submit() 不同的是使用 execute() 执行的任务是没有返回值的&#xff0c;使用 submit() 则是存在返回值的&#xff0c;这与接下里要说的 CompletableFuture.run…

实现异步编程,这个工具类你得掌握!

前言 最近看公司代码&#xff0c;多线程编程用的比较多&#xff0c;其中有对CompletableFuture的使用&#xff0c;所以想写篇文章总结下 在日常的Java8项目开发中&#xff0c;CompletableFuture是很强大的并行开发工具&#xff0c;其语法贴近java8的语法风格&#xff0c;与st…

Java异步编程之CompletableFuture

异步任务 Future获取异步任务结果 利用 Java 并发包提供的 Future 可以很容易获得异步任务的执行结果&#xff0c;无论异步任务是通过线程池 ThreadPoolExecutor 执行的&#xff0c;还是通过手工创建子线程来执行的。利用多线程可以快速将一些串行的任务并行化&#xff0c;从而…

JUC异步编程

什么是JUC JUC的意思是java并发编程工具包&#xff0c;是java.util.concurrent包的简称。目的就是为了更好的支持高并发任务&#xff0c;让开发者利用这个包进行的多线程开发时&#xff0c;可以有效的减少竞争条件和死锁线程。 异步编程 模拟用户下单操作。。。 1、根据地址…

线程、多线程的使用、线程池、异步(CompletableFuture)-48

一&#xff1a;线程 1.初始化线程的四种方式 1&#xff09;、继承 Thread public class ThreadTest {public static void main(String[] args) {System.out.println("main...start...");Thread01 thread new Thread01();//启动线程thread.start();System.out.pri…

CompletableFuture 执行异步任务

CompletableFuture 执行异步任务 参考&#xff1a; (10条消息) Java 8 的异步编程利器 CompletableFuture 真香&#xff01;_不才陈某的博客-CSDN博客 提供几十种方法&#xff0c;帮助异步任务执行调用&#xff1b; 主要包括&#xff1a; 创建异步任务任务异步回调多个任务…

CompletableFuture实现异步编排全面分析和总结

一、&#x1f308;CompletableFuture简介 CompletableFuture结合了Future的优点&#xff0c;提供了非常强大的Future的扩展功能&#xff0c;可以帮助我们简化异步编程的复杂性&#xff0c;提供了函数式编程的能力&#xff0c;可以通过回调的方式处理计算结果&#xff0c;并且提…

【Java8新特性--->异步处理】CompletableFuture

一、引入 假设一个商品详情页需要以下操作&#xff1a; 查询展示商品的基本信息耗时&#xff1a;0.5s查询展示商品的销售信息耗时&#xff1a;0.7s查询展示商品的图片信息耗时&#xff1a;1s查询展示商品销售属性耗时&#xff1a;0.3s查询展示商品规格属性耗时&#xff1a;1.…

CompletableFuture API

目录 1. 为什么要用CompletableFuture1.1 API 2. CompletableFuture Demo1. 创建CompletableFuture2. 定义CompletableFuture完成时和异常时需要回调的实例3. CompletableFuture的优点 3. demo&#xff1a;多个CompletableFuture串行执行4. demo&#xff1a;多个CompletableFut…

CompletableFuture实战与分析

Future对于结果的获取不够好&#xff0c;只能通过阻塞或者轮询的方式得到任务的结果。在Java8中Doug Lea大师提供了一个CompletableFuture工具类&#xff0c;可以更优雅的对异步并行操作进行编排。 Future VS CompletableFuture CompletableFuture支持手动完成任务&#xff0…