前端杂谈 · Web

Vue指令之【事件修饰符】

•̀.̫•́✧ · 6月29日 · 2020年本文2475字 · 阅读7分钟27

事件修饰符

  • .stop 阻止冒泡
  • .prevent 阻止默认事件
  • .capture 添加事件侦听器时使用事件捕获模式
  • .self 只当事件在该元素本身(比如不是子元素)触发时触发回调
  • .once 事件只触发一次

代码演示

使用 .stop 阻止冒泡

下列代码div1Handler( )不会被触发

<div class="inner" @click="div1Handler">
      <input type="button" value="戳他" @click.stop="btnHandler">
</div>

<script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        div1Handler() {
          console.log('这是触发了 inner div 的点击事件')
        },
        btnHandler() {
          console.log('这是触发了 btn 按钮 的点击事件')
        }
      }
    });
</script>

使用 .prevent 阻止默认行为

下列代码超链接点击后,不会跳转到指定网页

<a href="http://www.baidu.com" rel="nofollow noopener"  rel="nofollow noopener"  rel="nofollow noopener" rel="nofollow noopener" @click.prevent="linkClick">
       有问题,先去百度
</a>

使用 .capture 实现捕获触发事件的机制

下列代码.capture先执行父级的函数,再执行子级的触发函数(一般用法),即是给元素添加一个监听器,当元素发生冒泡时,先触发带有该修饰符的元素。若有多个该修饰符,则由外而内触发。

<div class="inner" @click.capture="div1Handler">
      <input type="button" value="戳他" @click="btnHandler">
</div>

<script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        div1Handler() {
          console.log('这是触发了 inner div 的点击事件')
        },
        btnHandler() {
          console.log('这是触发了 btn 按钮 的点击事件')
        }
      }
    });
</script>

要理解JavaScript事件冒泡与捕获机制,如下图,我对4个div分别设置了冒泡监听器和捕获监听器。当我们点击最里层的div时,事件的传递过程如上图所示。log()方法是我定义的,有在控制台输出的功能。点击一下“点击这里”,控制台会输出12344321。

Vue指令之【事件修饰符】-歪?是3.1415926吗

使用 .self 实现只有点击当前元素时候,才会触发事件处理函数

.self 是只有是自己触发的自己才会执行,如果接受到内部的冒泡事件传递信号触发,会忽略掉这个信号。

下列代码中,外层 div 会忽略掉内部 input 的冒泡事件。

<div class="inner" @click.self="div1Handler">
      <input type="button" value="戳他" @click="btnHandler">
</div>

<script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        div1Handler() {
          console.log('这是触发了 inner div 的点击事件')
        },
        btnHandler() {
          console.log('这是触发了 btn 按钮 的点击事件')
        }
      }
    });
</script>

.self 和 .stop 区别: .self 只是阻止自身不执行冒泡触发,不会阻止冒泡继续向外部触发, .stop 是从自身开始不向外部发射冒泡信号。

使用 .once 只触发一次事件处理函数

.once 是将事件设置为只执行一次,如 .click.prevent.once 代表只阻止事件的默认行为一次,当第二次触发的时候事件本身的行为会执行。

下列代码中,第一次点击超链接会触发linkClick( ) 点击事件,并不会跳转;第二次点击时,会跳转到指定的链接地址。

<a href="http://www.baidu.com" rel="nofollow noopener"  rel="nofollow noopener"  rel="nofollow noopener" rel="nofollow noopener" @click.prevent.once="linkClick">
    有问题,先去百度
</a>

<script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        linkClick() {
          console.log('触发了连接的点击事件')
        }
      }
    });
</script>

扩展

演示: .stop 和 .self 的区别

.self 只会阻止自己身上冒泡行为的触发,并不会真正阻止 冒泡的行为

<div class="outer" @click="div2Handler">
      <div class="inner" @click="div1Handler">
        <input type="button" value="戳他" @click.stop="btnHandler">
      </div>
</div>

<!-- <div class="outer" @click="div2Handler">
        <div class="inner" @click.self="div1Handler">
          <input type="button" value="戳他" @click="btnHandler">
        </div>
</div> -->

<script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        div1Handler() {
          console.log('这是触发了 inner div 的点击事件')
        },
        btnHandler() {
          console.log('这是触发了 btn 按钮 的点击事件')
        },
        div2Handler() {
          console.log('这是触发了 outer div 的点击事件')
        }
      }
    });
</script>
0 条回应