v-on 事件处理

事件绑定

Vue 中,所谓事件绑定,就是使用 v-on 指令监听 DOM 事件,从而在事件触发的时候,运行一些 JS 代码。

  • 有时,事件的处理逻辑比较复杂,直接放在 v-on 指令中是不可行的,v-on 还可以接收一个事件处理方法
  • 有时,需要访问原始的DOM事件,可以使用特殊变量 $event 传入方法中
<template>
  <div id="app">
    <div>{{num}}</div>

    <!-- v-on 指令用法 -->
    <button v-on:click="num++">点击+1</button>
    <!-- v-on 简写形式 -->
    <button @click="num--">点击-1</button>

    <!-- 事件处理方法,无参调用时,()可以省略 -->
    <button v-on:click="clickAdd1">点击+1方法</button>
    <button v-on:click="clickMinus1()">点击-1方法</button>
    <!-- 传递参数 -->
    <button v-on:click="clickAddN(3)">点击+3方法</button>
    <!-- 有时,需要访问原始的DOM事件,可以使用特殊变量$event传入方法中 -->
    <button v-on:click="say('HelloWorld',$event)">点击</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      num:0
    }
  },
  methods:{
    clickAdd1(){
      this.num++
    },
    clickMinus1(){
      this.num--
    },
    clickAddN(val){
      this.num += val;
    },
    say(val,event){
      if(event){
        event.preventDefault();  // 阻止默认事件
        event.stopPropagation();  // 阻止冒泡
      }
      // console.log(event.target.tagName)
      console.log(val)
    }
  }
}
</script>

事件修饰符

在事件处理程序中调用 event.preventDefault()或 event.stopPropagation()是非常常见的需求。

尽管可以在方法中轻松实现,但更好的方式是:方法中只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue 提供了事件修饰符:由以“点”开头的指令后缀来表示的

需说明的是,使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。

因此,用 v-on:click.prevent.self会阻止所有的点击,而 v-on:click.self.prevent只会阻止对元素自身的点击。

<template>
  <div id="app">
    <!-- .prevent 阻止默认事件 -->
    <a href="http://www.baidu.com" @click.prevent="doThis">百度</a>

    <!-- .self 只在当前元素自身时触发,而不是其内部元素 -->
    <div @click.self="doThis">  
      <!-- 点击子元素,不会触发事件 -->
      父元素<div>子元素</div>
    </div>

    <!-- .once 事件只触发一次 -->
    <div @click.stop.once="doThis">点击</div>  // 事件修饰符可以串联

    <!-- .stop 阻止冒泡 -->
    <!-- .captue 使用事件捕获模式(先处理自身事件,再处理内部元素事件) -->
    
    <!-- .passive 告诉浏览器你不想阻止事件的默认行为(passive和prevent冲突,不能同时绑定在一个监听器上) -->
    <!-- .passive修饰符尤其能够提升移动端的性能 -->
    <div v-on:scroll.passive="onScroll">...</div>  
  </div>
</template>

<script>
export default {
  methods:{
    doThis(){
      console.log('执行doThis')
    }
  }
}
</script>

<style>

按键( keyup )修饰符

Dom 中,监听键盘事件时,我们通常需要确认详细的按键( KeyboardEvent.key );

而,在 Vue 中,可以在监听键盘事件( keyup )时,添加按键修饰符:

<template>
  <div id="app">
   <!-- 方式 1 -->
    <input type="text" @keyup.enter="doThis">
    
    <!-- 方式 2:使用按键码(keycode)也是可以的,不过,keycode的事件用法已经被废弃了,可能不会被最新的浏览器支持 -->
    <input type="text" @keyup.13="doThis">
    <!-- 如何获取按键码 ?-->
    <input type="text" @keyup="handle">
  </div>
</template>

<script>
export default {
  methods:{
    doThis(){
      console.log('执行了')
    },
    handle(event){
      // 按键码,可以通过$event.keyCode获取
      console.log(event.keyCode);
    }
  }
}
</script>

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键名( 按键码的别名 ):

.enter
.tab
.delete    捕获‘删除’或‘退格’键
.esc
.space
.up
.down
.left
.right

系统修饰符

[ 2.1.0 新增 ] 可以使用系统修饰符来实现:仅在按下相应按键时,才触发鼠标或键盘事件的监听器

  • .ctrl
  • .shift
  • .alt
  • .meta      // 在 Mac 系统键盘上,meta 对应 command 键 ;而 Windows 系统键盘 meta 对应 Windows 键
<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>    // 只要按下了CTRL,然后点击就可以触发;问题在于,按下CTRL+任意其他键,然后点击,也可以触发

[ 2.5.0 新增 ] .exact 修饰符,允许控制由精确的系统修饰符组合触发的事件。

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

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

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

[ 2.2.0 新增 ] 鼠标按钮修饰符

// 这些修饰符会限制处理函数仅响应特定的鼠标按钮

.left            .right             .middle