【前端Tip】Vue事件修饰符

前言: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时,会同时触发childClickparentClick两个方法,最后输出:

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 向浏览器表明不想阻止事件的默认行为。

上面的总结太短了,容易记住,但不容易消化,还得需要在探索学习的过程中成长。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容