vue事件修饰符

271 阅读4分钟

1. 事件修饰符

我们在平时总会用到一些方法去处理我们的事件函数,比如阻止事件的默认行为 、阻止事件冒泡等等。那在Vue.js中,对这些操作进行了一个很简易的处理,那就是在我们绑定的事件后面加一个事件修饰符,这样能让我们一眼就能看出,该组件绑定了什么事件 、对事件做了什么处理。

  • .stop: 阻止事件冒泡,不让当前元素的事件继续往外触发,如阻止点击div内部事件,触发div事件。相当于event.stopPropagation()
  • .prevent:是阻止事件本身行为,如阻止超链接的点击跳转,form表单的点击提交。相当于event.preventDefault()
  • .capture: 启用事件捕获(与冒泡相反,从外到内进行事件捕获)
  • .self:是只有是自己触发的自己才会执行,如果接受到内部的冒泡事件传递信号触发,会忽略掉这个信号
  • .once:事件只执行一次,如 .click.prevent.once 代表只阻止事件的默认行为一次,当第二次触发的时候事件本身的行为会执行
  • .passive:与.prevent的作用相反,即不阻止默认行为,.passive 修饰符尤其能够提升移动端的性能。

1.1 stop 和 self 区别:

  • stop阻止冒泡事件,例如点击子元素不会冒泡到父元素事件
  <div
    class="father"
    @click="btnClick1"
  >
    <div
      class="children"
      @click="btnClick2"
    >
      <div
        class="grandson"
        @click="btnClick3"
      ></div>
    </div>
  </div>
  
  // js
    const btnClick1 = () => {
      console.log('father')
    }
    const btnClick2 = () => {
      console.log('children')
    }
    const btnClick3 = () => {
      console.log('grandson')
    }
    return {
      btnClick1,
      btnClick2,
      btnClick3
    }
  // 此时点击class="grandson"的盒子,控制台打印:grandson  children  father
  // 事件会从子级向父级冒泡,应该避免冒泡事件
  // 应该修改为:
  @click.stop="btnClick2"
  @click.stop="btnClick3"
  • self只有自己才能触发自己的事件,例如点击父元素内的子元素部分,不会触发父元素事件。 (例:点击dialog遮罩层会关闭dialog,此时遮罩层是最大的父级元素,直接给遮罩层添加@click="handleClose",这里会有问题:点击遮罩层的子级元素,例如红框部分,也会关闭。应改为@click.self="handleClose",此时只有点击遮罩层才会触发,点击它的子级元素并不会触发事件)

image.png

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

1.2 .prevent

阻止了事件的默认行为,相当于调用了event.preventDefault方法

<form v-on:submit.prevent="onSubmit"></form>

1.3 .capture

  • 完整的事件机制是:捕获阶段--目标阶段--冒泡阶段
  • 默认的呢,是事件触发从目标开始往上冒泡
  • 而事件捕获(从包含这个元素的顶层开始往下触发),与冒泡事件顺序相反 首先复习下 addEventListener()
  • addEventListener()可以监听事件的触发,来达到绑定事件的目的,他的原理是监听,当有事件触发的时候它就会做出相应的动作
  • 参数: addEventListener(event, function, useCapture);
event:字符串,表示需要监听的事件,事件前面不用加`on`。例如:单击事件直接可以写成`click`function:回调函数,表示事件触发后要执行的函数。
useCapture:布尔值 `true``false`。 不传的话默认为`false``true`表示监听事件的捕获阶段,`false`表示监听事件的冒泡阶段
    <div class="father">
      <div class="children">
      </div>
    </div>
   
     <script>
        var box1 = document.querySelector('.father')
        var box2 = document.querySelector('.children')
        box1.addEventListener('click', ()=> {
          console.log('father')
        }, true)
        box2.addEventListener('click', ()=> {
          console.log('children')
        }, true)
      </script>
      // 点击children盒子,控制台打印:father  children
      
        <script>
            var box1 = document.querySelector('.father')
            var box2 = document.querySelector('.children')
            box1.addEventListener('click', ()=> {
              console.log('father', '捕获阶段')
            }, true)
            box2.addEventListener('click', ()=> {
              console.log('children', '捕获阶段')
            }, true)

            box1.addEventListener('click', ()=> {
              console.log('father', '冒泡阶段')
            }, false)
            box2.addEventListener('click', ()=> {
              console.log('children', '冒泡阶段')
            }, false)
        </script>
        // 点击children盒子,控制台打印:
        // father 捕获阶段
        // children 捕获阶段
        // children 冒泡阶段
        // father 冒泡阶段

1.4 .once

  • 绑定了事件以后只能触发一次,第二次就不会触发
  • 不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。
<!-- 点击事件将只会触发一次 -->
<a @click.once="doThis"></a>

1.5 .passive

当我们在监听元素滚动事件的时候,会一直触发onscroll事件,在pc端是没啥问题的,但是在移动端,会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发,   -->
<!-- 而不会等待 `onScroll` 完成,                    -->
<!-- 以防止其中包含 `event.preventDefault()` 的情况  -->
<div @scroll.passive="onScroll">...</div>