vue3重走来时路之:事件处理的修饰符

2,714 阅读3分钟

vue事件处理中主要由 事件修饰符按键修饰符系统修饰符 三大类组成。

事件修饰符

  • .stop: 阻止单击事件继续冒泡
  • .prevent: 阻止浏览器的默认行为
  • .capture: 添加事件侦听器时使用事件捕获模式
  • .self: 只执行直接作用在该元素身上的事件,会忽略其他元素的冒泡或者捕获事件
  • .once: 事件只会触发一次
  • .passive: 告诉浏览器不用去查询,我们没用preventDefault阻止默认行为

下面我们来重点介绍一下这几个修饰符的意义

.stop

阻止单击事件继续冒泡

下面代码如果没加.stop,就会从内至外冒泡,依次执行:onStop(3)、onStop(2)、onStop(1),但是我们在onStop(3)的地方加上.stop,点击onStop(3)的时候就只会执行onStop(3),不会向外冒泡了

<div @click="onStop(1)">
  <div @click="onStop(2)">
    <div @click.stop="onStop(3)">.stop</div>
  </div>
</div>

.prevent

阻止浏览器的默认行为

例如:

  • 超链接的自动跳转
  • form标签中的submit按钮点击导致的页面刷新
  • 网页中右键单机,会弹出一个菜单。
// 阻止链接跳转
<a href='https://www.baidu.com/' @click.prevent='click1()'>可能跳转到百度</a>

// 提交事件不再重载页面
<form @submit.prevent="onSubmit"></form>

.capture

  • 添加事件侦听器时使用事件捕获模式
  • 当元素发生冒泡时,先触发带有该修饰符的元素。若有多个该修饰符,则由外而内触发。就是谁有该事件修饰符,就先触发谁。
  • 下面四个div的click都带有 .capture,这时候console.log顺序是:capture1、capture2、capture3、capture4。
  • 下面四个div的click如果都不带 .capture,这时候console.log顺序是:capture4、capture3、capture2、capture1
// capture示例
<div @click.capture="capture('capture1')">
  <div @click.capture="capture('capture2')">
    <div @click.capture="capture('capture3')">
      <div @click.capture="capture('capture4')">capture</div>
    </div>
  </div>
</div>

methods: {
  capture(text: string) {
    console.log(text);
  },
},

.self

只执行直接作用在该元素身上的事件,会忽略其他元素的冒泡或者捕获事件

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div @click.self="doThat">...</div>

.once

事件只会触发一次

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

.passive

告诉浏览器不用去查询,我们没用preventDefault阻止默认行为

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

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

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

  • 不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。
  • 这个 .passive 修饰符尤其能够提升移动端的性能。

按键修饰符

vue中未提供别名的按键, 可以使用键盘原始的key 值去绑定 但是要注意要转换为 tabab-case(短横线命名)

也可以自定义按键别名:Vue.config.keyCode 自定义键名 = 键码

常用按键别名如下:

  • .enter: 回车
  • .tab: 换行(特殊键, 必须配合keydown 去使用)
  • .delete: 捕获“删除”和“退格”键
  • .esc: 退回
  • .space: 空格
  • .up: 上
  • .down: 下
  • .left: 左
  • .right: 右
<input @keydown.tab="submit" />
<input @keyup.enter="submit" />

methods: {
  submit() {
    console.log(1111);
  },
},

系统修饰符

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
  • .meta
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

.exact 修饰符

.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

鼠标按钮修饰符

  • .left
  • .right
  • .middle
<div @click.right.prevent="submit">禁止鼠标右键默认事件</div>

methods: {
  submit() {
    console.log(1111);
  },
},