# 简介

​ Vue 提供了事件绑定的语法糖,我们在标签中可直接使用形如 v-on:click,@click,@focus 的形式绑定事件监听器,并且可以使用修饰符对事件进行 option 设置。本次解释下 prevent 与 passive 的修饰符。prevent 是拦截默认事件passive 是不拦截默认事件。

# prevent

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

图1.默认事件与事件传递

​ 如上图 1,我在第三次捕获后终止事件传递,但是最后输出了 1 2 3 x

图2.拦截默认事件

​ 如上图 2,我们在 a 标签上的 click 加个 prevent 的修饰符,最后输出 1 2 3 4 4 3 2 1。默认的 href 里的事件没有触发。

# passive

​ passive 这个修饰符会执行默认方法。你们可能会问,明明默认执行为什么会设置这样一个修饰符。这就要说一下这个修饰符的本意了。

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

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

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

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