vue3:事件处理event

222 阅读4分钟

事件处理

快速入门

在 Vue 中如果要给元素绑定事件,可以使用内置指令 v-on,使用该指定就可以绑定事件:

<template>
  <div>{{ count }}</div>
  <button v-on:click="add">+1</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
function add() {
  count.value++
}
</script>

<style scoped></style>

上面的事件示例非常简单,不过关于事件处理,有各种各样的细节。

事件处理各种细节

  1. 如果事件相关的处理比较简单,那么可以将事件处理器写成内连
<template>
  <div>{{ count }}</div>
  <button v-on:click="count++">+1</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>

<style scoped></style>

这种内连事件处理器用的比较少,仅在逻辑比较简单的时候可以快速完成事件的书写。

  1. 绑定事件是一个很常见的需求,因此 Vue 也提供了简写形式,通过 @ 符号就可以绑定事件
<button @click="count++">+1</button>

在日常开发中,更多的见到的就是简写形式。

  1. 向事件处理器传递参数
<template>
  <div>{{ count }}</div>
  <button @click="add('Hello World')">+1</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
function add(message) {
  count.value++
  console.log(message)
}
</script>

<style scoped></style>
  1. 事件对象
  • 没有传参:事件对象会作为一个额外的参数,自动传入到事件处理器,在事件处理器中,只需要在形参列表中声明一下即可
  • 如果有传参:这种情况下需要使用一个特殊的变量 $event 来向事件处理器传递事件对象
<template>
  <div>{{ count }}</div>
  <button @click="add">+1</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
// 事件对象会自动传入,直接在事件处理器的形参中声明即可
function add(event) {
  count.value++
  console.log(event)
  console.log(event.target)
  console.log(event.clientX, event.clientY)
}
</script>

<style scoped></style>
<template>
  <div>{{ count }}</div>
  <!-- 必须显式的使用 $event 来向事件处理器传递事件对象 -->
  <button @click="add('Hello World', $event)">+1</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
function add(message, event) {
  count.value++
  console.log(message)
  console.log(event)
  console.log(event.target)
  console.log(event.clientX, event.clientY)
}
</script>

<style scoped></style>

如果是箭头函数,写法如下:

<template>
  <div>{{ count }}</div>
  <!-- 如果是箭头函数,那么事件对象需要作为参数传入 -->
  <!-- 此时参数没有必须是 $event 的限制了 -->
  <button @click="(event) => add('Hello World', event)">+1</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
function add(message, event) {
  count.value++
  console.log(message)
  console.log(event)
  console.log(event.target)
  console.log(event.clientX, event.clientY)
}
</script>

<style scoped></style>

修饰符

之所以会有修饰符,是因为之前在书写原生事件处理的时候,事件处理器中经常会包含诸如阻止冒泡、阻止默认事件等非事件业务的逻辑。有了修饰符之后,可以使用事件修饰符来完成这些非核心的业务处理,让事件处理器更加专注于业务逻辑。

常见的事件处理器:

  • .stop:阻止事件冒泡
  • .prevent:阻止默认行为
  • .self:只有事件在该元素本身上触发时才触发处理函数(不是在子元素上)
  • .capture:改变事件的触发方式,使其在捕获阶段而不是冒泡阶段触发。
  • .once:事件只触发一次该元素上的处理函数
  • .passive:用于提高页面滚动的性能。

修饰符的使用也很简答:

<button @click.stop="handleClick">点击我</button>

下面是一个具体的示例:

<template>
  <button @click.once="clickHandle">click</button>
</template>

<script setup>
function clickHandle() {
  console.log('你触发了事件')
}
</script>

<style scoped></style>

另外需要说一下,事件修饰符是可以连用的,例如现在有这么一个需求,我们希望用户在点击按钮时:

  • 阻止事件冒泡(.stop)。
  • 阻止默认行为(.prevent),例如,防止表单提交。
  • 在捕获阶段触发事件处理器(.capture),确保在任何可能的冒泡前响应。
  • 事件处理器只触发一次(.once)。
<button @click.capture.stop.prevent.once>click</button>

在连用事件修饰符的时候,修饰符的顺序通常不会影响最终的行为,因为不同的修饰符代表对不同方面的行为的控制,相互是不冲突的。

除了事件修饰符以外,Vue 还提供了一组按键修饰符,按键修饰符主要是用于检查特点的按钮:

  • .enter
  • .tab
  • .delete (捕获“Delete”和“Backspace”两个按键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
  • .ctrl
  • .alt
  • .shift
  • .meta(不同的系统对应不同的按键)
<template>
  <input type="text" @keyup.enter="submitText" />
</template>

<script setup>
function submitText() {
  console.log('你要提交输入的内容')
}
</script>

<style scoped></style>

按键修饰符也是能够连用,比如上面的例子,我们修改为 alt + enter 是提交

<input type="text" @keyup.alt.enter="submitText" />

Mac 系统中 alt 对应的是 option 按键

有一个特殊的修饰符 .exact ,exact 该单词的含义是“精确、精准” ,该修饰符的作用在于控制触发事件的时候,必须是指定的按键组合,不能够有其他按键。

<button @click.ctrl="onClick">A</button>

在上面的例子中,指定按下 ctrl 键触发事件,但是假设我现在同时按下 alt 和 ctrl 也会触发事件

<button @click.ctrl.exact="onClick">A</button>

添加了 .exact 修饰符之后,表示只有在按下 ctrl 并且没有按下其他按键的时候才会触发事件

最后还有三个鼠标按键修饰符,用于指定特定的鼠标按键:

  • .left
  • .right
  • .middle
<template>
  <button class="context-menu-button" @contextmenu.prevent.right="handleRightClick">
    右键点击
  </button>
</template>

<script setup>
function handleRightClick() {
  console.log('你点击了鼠标右键')
}
</script>

<style scoped>
.context-menu-button {
  padding: 10px 20px;
  cursor: context-menu; /* 显示适当的鼠标指针 */
  background-color: #f5f5f5;
  border: 1px solid #ccc;
  border-radius: 5px;
}
</style>

官方文档:事件处理 | Vue.js


-EOF-