轻云听书app
17.87MB · 2025-10-15
在开发中,你是否遇到过这些“意外”?
这些问题的根源,都是事件流控制不当。
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 交互将更加精准、高效、优雅。
“李鬼”再现: PlayStation 商店惊现《黑神话:悟空》山寨游戏
23000Pa 吸力:小米米家扫地机器人 5 Pro 薄嵌上下水版国补后 2931 元