六维教程

Vue3 事件处理

按钮点击、表单提交、键盘输入……页面的所有交互都靠事件驱动。

Vue 用 v-on(简写 @)绑定事件,写法比原生 addEventListener 干净,还自带一套修饰符省去模板代码。

基础绑定

@事件名="处理函数",事件触发时执行对应逻辑:

<script setup>
import { ref } from 'vue'

const count = ref(0)

const add = (n = 1) => {
  count.value += n
}
</script>

<template>
  <p>点击数:{{ count }}</p>

  <!-- 直接调用方法 -->
  <button @click="add">+1</button>

  <!-- 内联写法,传参数 -->
  <button @click="add(5)">+5</button>

  <!-- 内联表达式(最简单) -->
  <button @click="count++">直接加</button>
</template>

三种写法都支持:

写法 示例 使用场景
方法处理器 @click="add" 逻辑较多时
内联 + 传参 @click="add(5)" 需要传参数
内联表达式 @click="count++" 一句话就能搞定

事件对象 $event

处理函数里常常需要拿事件对象(获取输入框值、阻止默认行为等)。

最省事的写法是不传参@submit="submit" 时,Vue 会把事件对象自动作为第一个参数传进去,所以 submit 的第一个形参 e 就直接是事件对象:

<script setup>
const submit = (e) => {
  e.preventDefault()          // 阻止表单默认刷新
  console.log(e.target.value)
}
</script>

<template>
  <form @submit="submit">
    <input placeholder="随便输入点什么" />
    <button type="submit">提交</button>
  </form>
</template>

内联写法里要传事件对象,就得手动用特殊变量 $event

<button @click="add(5, $event)">加 5 并看事件</button>

$event 的位置随你安排,但 JS 形参的顺序要和模板里一致:

<button @click="add(5, $event)">加 5 并看事件</button>
<button @click="add2($event, 5)">事件在前也可以</button>
const add = (num, e) => {       // e 收到事件对象
  console.log(num, e.target)
}
const add2 = (e, num) => {      // 顺序和模板里保持一致
  console.log(e.target, num)
}

修饰符

修饰符用 . 跟在事件名后面,用来调整事件的默认行为,是 Vue 最省心的部分。

修饰符分两类:

  • 事件修饰符:调整”事件怎么跑”
  • 按键修饰符:限定”按了哪个键才触发”

事件修饰符

修饰符 作用 示例
.stop 阻止事件冒泡 @click.stop
.prevent 阻止默认行为 @submit.prevent
.self 只当点击元素自身时触发 @click.self
.once 只触发一次 @click.once
.capture 用捕获阶段(先父后子) @click.capture
.left/.right/.middle 指定鼠标按键 @click.middle

修饰符可以连写:@click.stop.prevent 同时阻止冒泡和默认行为。

按键修饰符

按键修饰符限定触发条件与”键”有关,又分两种:键盘键名(按到指定键才触发)和系统修饰键(必须同时按住):

修饰符 作用 示例
.enter 键盘键名,按键匹配才触发 @keyup.enter
.ctrl 系统修饰键必须同时按下 @click.ctrl

几个高频例子:

<!-- 点击子元素不连带到父级 -->
<div @click="onDivClick">
  <button @click.stop="onBtnClick">点我</button>
</div>

<!-- 表单提交阻止刷新页面,是最常见的 -->
<form @submit.prevent="submitForm"></form>

<!-- 鼠标按下时阻止默认行为:不选中文本、不触发原生拖拽,常用于自定义拖拽 -->
<div @mousedown.prevent="onDrag">拖我</div>

<!-- 按回车才触发搜索 -->
<input @keyup.enter="search" />

<!-- 长按 Ctrl 再点击才生效 -->
<button @click.ctrl="toggle">Ctrl+点击</button>

速查卡片

需求 写法
普通点击 @click="fn"
传参 + 事件对象 @click="fn(arg, $event)"
阻止冒泡 @click.stop
阻止默认行为 @submit.prevent
键盘触发 @keyup.enter="search"
只触发一次 @click.once
组合修饰符 @keyup.ctrl.enter@click.stop.prevent
上一篇
Vue3 列表渲染
下一篇
Vue3 表单绑定