前言:Vue文档中对于事件修饰符介绍就是一句话,如果只是看那简单的介绍,真的是不明白,不会用。
在实际开发时,遇到了一个问题,如何禁止蒙层下的div滚动,最后百度下需要使用.prevent
修饰符(说明之前白看了,不理解就等于没学),所以这里特地学习记录下Vue常用事件修饰符的使用。
1. 事件修饰符
Vue为v-on
提供了事件修饰符,修饰符就是用.
表示的指令后缀,如下:
- .stop
- .prevent
- .self
- .capture
- .once
- .passive
使用方式很简单,就是在v-on:click
后面增加.stop
等修饰符,如下:
<!-- 单击事件将停止冒泡传递 -->
<a v-on:click.stop="doThis"></a>
也支持链式书写,使用多个不同的修饰符,如下:
<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>
使用多个修饰符时需要注意调用顺序,因为相关代码是以相同的顺序生成的。因此使用 @click.prevent.self 会阻止元素及其子元素的所有点击事件的默认行为而 @click.self.prevent 则只会阻止对元素本身的点击事件的默认行为。官网上的这段话的不同实现可以参考:https://www.likecs.com/show-308577054.html。
2. 具体使用
2.1 .stop
.stop 用于阻止事件的冒泡传递。
当一个HTML元素产生一个事件时,该事件会在元素节点与根节点之间的路径传播,路径所经过的节点会收到该事件,这个传播的过程叫做DOM事件流。
默认情况下单击事件是冒泡传递的,A是B的父节点,A和B都有各自的点击事件,当点击B时,A和B的点击事件都会被触发,先响应自身的事件,再响应父节点的事件。示例如下:
...
<div style="height:100px;background-color:blue;" @click="parentClick">
<div style="height:50px;width:50px;background-color:red;" @click="childClick">
</div>
</div>
...
...
methods: {
childClick(){
console.log("childClick");
},
parentClick(){
console.log("parentClick");
},
}
...
点击里面的div时,会同时触发childClick
和parentClick
两个方法,最后输出:
childClick
parentClick
但是通常情况下,我们的需求是点击里面的div,外层的div不能响应事件。这就用到了.stop
事件修饰符,修改后如下:
...
<div style="height:100px;background-color:blue;" @click="parentClick">
<div style="height:50px;width:50px;background-color:red;" @click.stop="childClick">
</div>
</div>
...
这样,点击里面的div时,只会输出childClick
了。
2.2 .prevent
.prevent 阻止事件的默认行为。
html中有一些标签是自带默认行为的:比如a标签,点击的时候会自动跳转到目标链接网页中,代码如下:
<a href="https://www.baidu.com">百度</a>
当我们想使用a标签,给a标签增加一个点击事件aClick
,代码如下:
<a href="https://www.baidu.com" @click="aClick">哈哈哈</a>
点击a标签的时候,除了正常响应aClick
事件,同时也会跳转到https://www.baidu.com
页面。
但是,如果我们点击a标签的时候,只想响应自己的事件,不想跳转,那就需要用到.prevent
了,代码如下:
<a href="https://www.baidu.com" @click.prevent="aClick">哈哈哈</a>
最上面说的是如何禁止蒙层下的div滚动,用到的就是.prevent
,代码如下:
<div @touchmove.prevent v-show="true"></div>
个人理解就是把滑动手势所带来的默认行为(页面滑动)阻止了,所以蒙层下面的页面不会进行滑动了。
这个问题应该还有其他更好的方案可以实现,这里只是举例说明!😄
2.3 .self
.self 仅当 event.target 是元素本身时才会触发事件处理器。
举个例子,A是B的父节点,B是C的父节点,A和B和C都有各自的点击事件,当点击C时,A和B和C的点击事件都会响应。如果点击C的时候,不让B响应事件,让A响应事件,该如何处理?
这就用到.self
修饰符了,当点击C的事件冒泡时会自动跳过使用.self
修饰符元素B,因为点击事件event.target是C,并不是B。所以示例代码如下:
...
<div style="height:100px;background-color:blue;" @click="aClick">
<div style="height:50px;background-color:red;" @click.self="bClick">
<div style="height:25px;background-color:purple;" @click="cClick">
</div>
</div>
</div>
...
当然,点击B的时候,可以正常响应B的点击事件,因为event.target是B本身。
.capture
、.once
和.passive
修饰符与原生addEventListener
事件相对应,关于addEventListener
可见菜鸟教程关于该篇的介绍。
2.4 .capture
.capture 添加事件监听器时,使用 capture
捕获模式。
举个例子,A是B的父节点,A和B都有各自的点击事件,当点击B时,A和B的点击事件都会响应,响应顺序是B->A,当使用.capture
修饰符后,说明使用捕获模式,响应顺序是A->B,代码如下:
<div style="height:100px;background-color:blue;" @click.capture="log('a')">
<div style="height:80px;background-color:red;" @click="log('b')">
<div style="height:40px;background-color:yellow;" @click.self="log('c')">
</div>
</div>
</div>
当点击B的时候,会依次输出a、b了。
当点击C的时候,输出的是a、c、b,因为A用了.capture
,先捕获了点击事件,输出a,处理完之后还会走默认的冒泡,所以会先输出c,最后输出b。
2.5 .once
.once 可以让事件最多被触发一次。
这个就很好理解了,只响应一次事件,示例如下:
<div style="height:100px;background-color:blue;" @click.once="log('a')">
</div>
事件只有在第一次点击时生效,只会输出一个a。
2.6 .passive
.passive 向浏览器表明不想阻止事件的默认行为。
就是告诉浏览器,你可以不用去查询程序有没有阻止默认事件,也就是提前告诉浏览器程序不会阻止,那么意义是什么呢?
比如你有一个朋友要来你家,他如果提前告诉你,那么你可以提早准备午餐打扫卫生等,但是如果没有告诉,只有在等他进门时你才知道,那个时候你就来不及了。这也就是.passive提前告诉浏览器的原因,提早告诉,提高性能。
所以就有了官网上那句话:.passive
修饰符一般用于触摸事件的监听器,可以用来改善移动端设备的滚屏性能。
<!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 -->
<!-- 以防其中包含 `event.preventDefault()` -->
<div @scroll.passive="onScroll">...</div>
3. 总结
.stop 用于阻止事件的冒泡传递。
.prevent 阻止事件的默认行为。
.self 仅当 event.target 是元素本身时才会触发事件处理器。
.capture 添加事件监听器时,使用 capture
捕获模式。
.once 可以让事件最多被触发一次。
.passive 向浏览器表明不想阻止事件的默认行为。
上面的总结太短了,容易记住,但不容易消化,还得需要在探索学习的过程中成长。