# Vue事件处理

前面的话

Vue事件监听的方式貌似违背了**关注点分离(separation of concern)**的传统理念。 实际上,所有的Vue.js事件处理方法和表达式都严格绑定在当前视图的ViewModel上,它不会导致维护上的困难。 使用v-on有以下好处:

  • 1、扫一眼HTML模板便能轻松定位在JS代码里对应的方法
  • 2、无须在JS里手动绑定事件,ViewModel代码可以是非常纯粹的逻辑,和DOM完全解耦,更易于测试
  • 3、当一个ViewModel被销毁时,所有的事件处理器都会自动被删除。无须担心如何自己清理它们

# 事件监听

通过 v-on 指令来绑定事件监听器

<div id="example">
    <button v-on:click="counter += 1">增加 1</button>
    <p>这个按钮被点击了 {{ counter }} 次。</p>
</div>
<script>
var example = new Vue({
  el: '#example',
  data: {
    counter: 0
  }
})
</script>

# 简写v-on

TIP

v-on:click === @click

# methods选项

许多事件处理的逻辑都很复杂,所以直接把JS代码写在 v-on 指令中有时并不可行。v-on指令可以接收一个定义的方法来调用。

WARNING

[注意]不应该使用箭头函数来定义 methods 函数,因为箭头函数绑定了父级作用域的上下文,所以this将不会按照期望指向 Vue 实例

<div id="example">
   <button @click="recordClickCount">点击记录次数</button>
   <p>{{ message }}</p>
</div>
<script>
var example = new Vue({
    el: '#example',
    data:{
        counter:0,
        message:''
    },
    methods: {
        recordClickCount(event) {
            if (event) {
                this.message = event.target.innerHTML + '被按下' + ++this.counter + '次';
            }
        }
    }
})
</script>

# 内联语句

除了直接绑定到一个方法,也可以用内联JS语句

<div id="example">
    <button v-on:click="say('hi')">Say hi</button>
    <button v-on:click="say('what')">Say what</button>
    <p>{{message}}</p>
</div>
<script>
var example = new Vue({
    el: '#example',
    data:{
        message:''
    },
    methods: {
        say: function (message) {this.message = message;}
    }
})
</script>

# 内联语句$event

<div id="example">
    <button v-on:click="say('hi',$event)">Say hi</button>
    <button v-on:click="say('what',$event)">Say what</button>
    <p>{{message}}</p>
</div>
<script>
var example = new Vue({
    el: '#example',
    data:{
        message:''
    },
    methods: {
        say(message,event) {
            if(event){
                event.preventDefault();
            }  
            this.message = message;
        }
    }
})
</script>

# 事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation()是非常常见的需求。 尽管可以在methods中轻松实现这点,但更好的方式:methods只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题, Vue.js 为v-on提供了事件修饰符。通过由点(.)表示的指令后缀来调用修饰符

.stop    // 阻止冒泡
.prevent // 阻止默认事件
.capture // 使用事件捕获模式
.self    // 只在当前元素本身触发
.once    // 只触发一次
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联  -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当事件在该元素本身(比如不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

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

# 鼠标修饰符@mouseup

.left   // 左键
.right  // 右键
.middle // 滚轮
<button @mouseup.right="right" @mouseup.middle="middle" @mouseup.left="left">{{message}}</button>

# 键值修饰符@keyup

在监听键盘事件时,经常需要监测常见的键值。 Vue 允许为 v-on 在监听键盘事件时添加关键修饰符

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

.enter   // 回车
.tab     // 制表键
.delete  // (捕获 “删除” 和 “退格” 键)
.esc     // 返回
.space   // 空格
.up      // 上
.down    // 下
.left    // 左
.right   // 右

# 自定义键值修饰符别名

可以通过全局 config.keyCodes 对象自定义键值修饰符别名

// 可以使用 v-on:keyup.a
Vue.config.keyCodes.a = 65

{/* 
<div id="example">
  <button @keyup.a="a"  @keyup.b="b">{{message}}</button>
</div> 
*/}

<script>
Vue.config.keyCodes.a = 65;
Vue.config.keyCodes.b = 66;
var example = new Vue({
  el: '#example',
  data:{
    message:'按下键盘上的a键或b键'
  },
  methods:{
    a(){
      this.message = 'a'
    },
    b(){
      this.message = 'b'
    },    
  }
})
</script>

# 修饰键

可以用如下修饰符开启鼠标或键盘事件监听,使在按键按下时发生响应

.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
{/* 
<div id="example">
    <button @click.ctrl="ctrl"  @click.alt="alt"  @click.shift="shift"  @click.meta="meta">{{message}}</button>
</div> 
*/}

<script>
var example = new Vue({
  el: '#example',
  data:{
    message:'分别用按住辅助键ctrl、alt、shift、meta进行点击,会出现不同的效果'
  },
  methods:{
    ctrl(){
      this.message = 'ctrl'
    },
    alt(){
      this.message = 'alt'
    },
    shift(){
      this.message = 'shift'
    },  
    meta(){
      this.message = 'meta'
    },           
  }
})
</script>
Last Updated: 2/21/2023, 2:57:45 PM