Appearance
✨ 事件处理 👌
快速入门
在 Vue 中使用 v-on(缩写为 @)为元素绑定事件:
vue
<template>
<div>{{ count }}</div>
<button v-on:click="add">+1</button>
<button @click="add">+1(简写)</button>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
function add() {
count.value++;
}
</script>书写建议
- 常规写法使用方法引用(如
@click="add"),语义清晰且便于复用。 - 简写
@是日常首选;根据团队规范统一风格即可。
处理器写法与传参
事件处理器可写为方法、内联表达式或箭头函数:
vue
<template>
<div>{{ count }}</div>
<!-- 方法引用 -->
<button @click="add">+1</button>
<!-- 内联表达式(逻辑极简单场景) -->
<button @click="count++">+1</button>
<!-- 传参调用 -->
<button @click="addWithMsg('Hello World')">+1</button>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
function add() {
count.value++;
}
function addWithMsg(message) {
count.value++;
console.log(message);
}
</script>可读性与性能
- 复杂逻辑尽量写成方法,避免在模板内堆叠三元/长表达式。
- 在大列表中避免为每项创建箭头函数,优先方法引用提升可读性和复用性。
事件对象与 $event
不传参时,原生事件对象会自动作为额外参数传入;传参时用 $event 显式传递:
vue
<template>
<button @click="onClick">+1</button>
</template>
<script setup>
function onClick(event) {
console.log(event.target, event.clientX, event.clientY);
}
</script>vue
<template>
<button @click="onClickWithMsg('Hello', $event)">+1</button>
</template>
<script setup>
function onClickWithMsg(message, event) {
console.log(message, event.type);
}
</script>箭头函数时直接接收事件对象:
vue
<template>
<button @click="(e) => onClickWithMsg('Hello', e)">+1</button>
</template>$event 的场景
当既要传自定义参数又要拿到原生事件对象时,使用 $event 传递更直观。
修饰符
修饰符用于处理非核心业务(阻止冒泡、阻止默认、捕获、一次性等),让处理器专注业务逻辑:
.stop:阻止事件冒泡.prevent:阻止默认行为.self:仅当事件在元素本身触发时才处理(非子元素).capture:在捕获阶段触发处理器.once:事件只触发一次.passive:提升滚动相关事件的性能
vue
<template>
<div @click="parent">
<button @click.stop="child">阻止冒泡</button>
<form @submit.prevent="submit">阻止默认提交</form>
<div class="overlay" @click.self="close">点击遮罩本身才关闭</div>
</div>
</template>
<script setup>
function parent() {
console.log("parent");
}
function child() {
console.log("child");
}
function submit() {
console.log("submitted");
}
function close() {
console.log("closed");
}
</script>关于 .passive
- 在被标记为
passive的监听器中调用event.preventDefault()将被忽略并触发控制台警告。 - 适用于
touchstart/touchmove、wheel等滚动相关事件以提升性能。
修饰符连用
修饰符可连用,组合不同维度的行为控制:
vue
<button @click.capture.stop.prevent.once="handle">click</button>
<script setup>
function handle() {
console.log("handled once in capture phase");
}
</script>顺序影响
不同修饰符侧重点不同(传播、默认行为、阶段、次数),通常连用时顺序不影响最终结果。
按键修饰符
用于键盘事件的快捷判断:
.enter.tab.delete(含 Delete & Backspace).esc.space.up.down.left.right- 组合:
.ctrl.alt.shift.meta
vue
<template>
<input type="text" @keyup.enter="submitText" />
<input type="text" @keyup.alt.enter="submitText" />
</template>
<script setup>
function submitText() {
console.log("提交输入内容");
}
</script>.meta 与平台
Windows/Linux 下为 Windows 键;macOS 为 Command 键。
精确匹配:.exact
要求仅在指定组合按下、且无其他按键参与时触发:
vue
<button @click.ctrl.exact="onClick">只在单独按下 Ctrl 时触发</button>鼠标按键修饰符
指定特定的鼠标按键:.left .right .middle。右键示例:
vue
<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>进阶:组件自定义事件(简述)
组件之间的事件通信使用 defineEmits:
vue
<!-- 子组件 -->
<script setup>
const emit = defineEmits(["submit"]);
function onSubmit(payload) {
emit("submit", payload);
}
</script>
<!-- 父组件 -->
<Child @submit="handleSubmit" />区分场景
DOM 事件用 v-on/@;组件事件用 defineEmits + emit。
小结
- 优先使用方法引用绑定事件,逻辑简单时可用内联或箭头函数。
$event用于在传参场景显式传递原生事件对象;箭头函数可直接接收事件对象。- 修饰符让处理器聚焦业务逻辑;滚动相关场景慎用
.passive与preventDefault。 - 按键与鼠标修饰符提升可读性;
.exact控制精确组合匹配。 - 组件事件通过
defineEmits/emit进行通信,与 DOM 事件区分使用。
