好书友
15.92MB · 2025-12-20
在开发中,你是否遇到过这些“意外”?
这些问题的根源,都是事件流控制不当。
Vue 提供了强大的 事件修饰符(Event Modifiers),让你无需在方法中写 event.stopPropagation() 或 event.preventDefault(),只需一个简洁的语法即可精准控制事件行为。
事件修饰符是 Vue 提供的特殊后缀,用 . 表示,用于修改事件的行为,让事件处理更声明式、更清晰。
<template>
<!-- 无修饰符 -->
<button @click="doSomething">Click</button>
<!-- 使用修饰符 -->
<button @click.stop="doSomething">Stop Propagation</button>
<button @click.prevent="doSomething">Prevent Default</button>
</template>
.stop —— 阻止事件冒泡等同于 event.stopPropagation(),阻止事件向上级元素传播。
<template>
<div class="card" @click="cardClicked">
<button @click="btnClicked">按钮</button>
</div>
</template>
<script>
export default {
methods: {
cardClicked() {
alert('卡片被点击');
},
btnClicked() {
alert('按钮被点击');
}
}
}
</script>
.stop:<button @click.stop="btnClicked">按钮</button>
.card。.prevent —— 阻止默认行为等同于 event.preventDefault(),取消元素的默认动作。
<form @submit.prevent="handleSubmit">
<input v-model="email" type="email" required>
<button type="submit">提交</button>
</form>
methods: {
handleSubmit() {
// 不会刷新页面!
api.submit(this.email).then(() => {
this.$message.success('提交成功!');
});
}
}
<a @click.prevent="openModal"><div @contextmenu.prevent>.capture —— 事件捕获模式改变事件流方向,使用捕获阶段而非默认的冒泡阶段。
window → document → 父元素 → ... → 目标元素;body → document。<div @click.capture="outerClick"> <!-- 先执行 -->
<div @click="innerClick">按钮</div> <!-- 后执行 -->
</div>
innerClick → outerClick.capture:outerClick(捕获) → innerClick(冒泡).self —— 仅当事件源是自身时触发只有当 event.target 是元素本身时才触发,不包含子元素。
<div class="modal" @click.self="closeModal">
<div class="content">
这是弹窗内容
<button @click="edit">编辑</button>
</div>
</div>
.modal {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
}
.modal 背景)→ 关闭弹窗;.content 或按钮 → 不关闭,因为 event.target 是子元素。.once —— 事件只触发一次监听器只触发一次,之后自动移除。
<!-- 只欢迎一次 -->
<button @click.once="showWelcome">点击我</button>
<!-- 首次加载提示 -->
<div @scroll.once="loadMoreData"></div>
<!-- 防止重复提交 -->
<form @submit.prevent.once="submitForm">
<button type="submit">提交</button>
</form>
methods: {
showWelcome() {
this.$message.info('欢迎访问!');
}
}
修饰符可以按需组合,顺序不影响结果。
<form @submit.prevent.stop.once="submitForm">
<button type="submit">提交</button>
</form>
prevent:阻止页面刷新;stop:防止事件冒泡到外层容器;once:防止重复提交。<div @click.capture.self="handleOutsideClick">
<!-- 内容 -->
</div>
capture:在捕获阶段监听;self:确保点击的是遮罩层本身;.passive —— 提升滚动性能告诉浏览器该事件处理器不会调用 preventDefault(),从而可以提前滚动,提升移动端流畅度。
<!-- 在滚动容器上 -->
<div @touchstart.passive="onTouchStart"></div>
虽然不属于“事件流”修饰符,但同样强大:
| 修饰符 | 键码 |
|---|---|
.enter | Enter |
.tab | Tab |
.delete | Delete / Backspace |
.esc | Escape |
.space | Space |
.up / .down / .left / .right | 方向键 |
<input @keyup.enter="search" placeholder="输入后按回车搜索">
<button @click.ctrl="secretAction">Ctrl + Click 触发隐藏功能</button>
| 修饰符 | 作用 | 类比 JS 方法 |
|---|---|---|
.stop | 阻止冒泡 | stopPropagation() |
.prevent | 阻止默认行为 | preventDefault() |
.capture | 捕获模式 | addEventListener(..., true) |
.self | 仅自身触发 | if (e.target === e.currentTarget) |
.once | 只触发一次 | removeEventListener() |
.passive | 优化性能 | { passive: true } |
最佳实践建议:
event.xxx();.prevent 和 .stop 是最常用的两个。掌握这些修饰符,你的 Vue 交互将更加精准、高效、优雅。