同学们好,我是 Eugene(尤金),一个拥有多年中后台开发经验的前端工程师~
(Eugene 发音很简单,/juːˈdʒiːn/,大家怎么顺口怎么叫就好)
你是否也有过:明明学过很多技术,一到关键时候却讲不出来、甚至写不出来?
你是否也曾怀疑自己,是不是太笨了,明明感觉会,却总差一口气?
就算想沉下心从头梳理,可工作那么忙,回家还要陪伴家人。
一天只有24小时,时间永远不够用,常常感到力不从心。
技术行业,本就是逆水行舟,不进则退。
如果你也有同样的困扰,别慌。
从现在开始,跟着我一起心态归零,利用碎片时间,来一次彻彻底底的基础扫盲。
这一次,我们一起慢慢来,扎扎实实变强。
不搞花里胡哨的理论堆砌,只分享看得懂、用得上的前端干货,
咱们一起稳步积累,真正摆脱“面向搜索引擎写代码”的尴尬。
做前端时经常看到
@click.stop、v-model.trim、@keyup.enter这类写法,刚入门会觉得“这些点后面的东西到底是干啥的”,写久了也可能说不清什么时候用.self、什么时候用.stop。
这篇咱们不聊底层原理,只讲:日常写代码该用哪个、为什么用、容易踩哪些坑,目标是让你看完就能在项目里正确选用。
一、修饰符是什么?先搞懂这个
修饰符:跟在指令后面、用点 . 连起来的小尾巴,用来改变指令的默认行为。
可以理解为:
原来的指令是「正常执行」,加了修饰符后变成「在某种条件下、按某种方式执行」。
常见形式:
@click.stop → 点击事件 + 阻止冒泡
v-model.trim → 双向绑定 + 自动去空格
@keyup.enter → 键盘抬起 + 只有按回车才触发
一句话:修饰符让指令更精确、更符合业务需求。
二、Vue 事件修饰符:用得最多
事件修饰符用来控制事件传播和默认行为。
2.1 常用事件修饰符一览
| 修饰符 | 作用 | 常见场景 |
|---|---|---|
.stop | 阻止事件冒泡 | 子元素有点击,不想触发父元素点击 |
.prevent | 阻止默认行为 | 表单提交、链接跳转 |
.capture | 使用捕获模式 | 父级先于子级触发(少用) |
.self | 只有 event.target 是自己时才触发 | 点蒙层关闭弹窗,点内容不关 |
.once | 只触发一次 | 抽奖、首次点击引导 |
.passive | 不调用 preventDefault | 滚动性能优化(移动端) |
2.2 完整示例
<template>
<!-- 场景1:卡片内有删除按钮,点删除不要触发行点击 -->
<div class="card" @click="goToDetail">
<h3>{{ title }}</h3>
<button @click.stop="deleteCard">删除</button>
<!-- .stop 阻止冒泡,点删除不会触发 goToDetail -->
</div>
<!-- 场景2:表单提交,阻止默认刷新 -->
<form @submit.prevent="onSubmit">
<input v-model="name" />
<button type="submit">提交</button>
</form>
<!-- 场景3:弹窗蒙层 - 点蒙层(遮罩层)关闭,点内容不关闭 -->
<div class="modal-overlay" @click.self="closeModal">
<div class="modal-content">
<p>我是弹窗内容,点我不会关闭</p>
</div>
</div>
<!-- 场景4:抽奖按钮,只能点一次 -->
<button @click.once="doLottery">立即抽奖</button>
</template>
<script>
export default {
data() {
return { title: '卡片标题', name: '' }
},
methods: {
goToDetail() { console.log('进入详情') },
deleteCard() { console.log('删除卡片') },
onSubmit() { console.log('提交表单') },
closeModal() { console.log('关闭弹窗') },
doLottery() { console.log('抽奖') }
}
}
</script>
2.3 .self 和 .stop 的区别
.stop:阻止冒泡,父级不会再收到事件.self:只在自己被直接点击时触发,子元素冒泡上来的事件不处理
弹窗场景:点内容会冒泡到蒙层,如果蒙层用 @click 而不是 @click.self,点内容也会关闭;用 .self 后,只有直接点蒙层才会关闭。
三、Vue v-model 修饰符:表单必会
v-model 本质是 :value + @input 的语法糖,修饰符用来控制何时更新、如何转换输入值。
3.1 三个修饰符
| 修饰符 | 作用 | 常见场景 |
|---|---|---|
.lazy | 从 input 改为 change 触发 | 搜索框、大表单,减少频繁计算 |
.number | 自动转成数字 | 年龄、数量等数字输入 |
.trim | 自动去掉首尾空格 | 用户名、手机号、邮箱等 |
3.2 为什么要 .number?
即使 type="number",v-model 绑定值默认还是字符串。
<template>
<input v-model="age" type="number" />
<!-- 用户输入 18,age 实际是 "18" 字符串 -->
</template>
<script>
export default {
data() { return { age: '' } },
watch: {
age(val) {
console.log(typeof val) // 没有 .number 时输出 "string"
}
}
}
</script>
加 .number 后:
<input v-model.number="age" type="number" />
<!-- 用户输入 18,age 是数字 18 -->
3.3 组合使用
<!-- 失焦/回车时更新,并去空格 -->
<input v-model.lazy.trim="keyword" placeholder="搜索" />
<!-- 数字 + 去空格(对数字输入通常意义不大, trim 主要用于文本) -->
<input v-model.number.trim="count" type="number" />
四、Vue 按键修饰符:别写 keyCode
直接用语义化修饰符,不必再记 keyCode。
4.1 内置别名
.enter .tab .delete .esc .space
.up .down .left .right
4.2 示例
<!-- 回车提交搜索 -->
<input v-model="keyword" @keyup.enter="search" placeholder="输入后按回车搜索" />
<!-- ESC 取消/关闭 -->
<input @keyup.esc="cancel" />
<!-- 支持链式:Ctrl + 回车 -->
<input @keyup.ctrl.enter="submit" />
4.3 自定义按键
Vue 2 中:
// main.js 或 组件内
Vue.config.keyCodes.f2 = 113
<input @keyup.f2="handleF2" />
Vue 3 移除了 keyCodes,需要自己判断:
<input @keyup="(e) => e.key === 'F2' && handleF2()" />
五、Vue 鼠标按键修饰符
| 修饰符 | 对应按键 |
|---|---|
.left | 左键 |
.right | 右键 |
.middle | 中键 |
<!-- 右键菜单:一般要 .prevent 阻止浏览器默认菜单 -->
<div @contextmenu.right.prevent="showCustomMenu">右键看看</div>
<!-- 中键点击 -->
<button @click.middle="middleClick">中键点击</button>
六、Vue 系统修饰键
需要配合 Ctrl、Alt、Shift、Meta(Win 徽标键 / Mac Command)使用。
| 修饰符 | 对应键 |
|---|---|
.ctrl | Ctrl |
.alt | Alt |
.shift | Shift |
.meta | Win / Command |
<!-- 按住 Ctrl 点击 -->
<div @click.ctrl="handleCtrlClick">按住 Ctrl 点击我</div>
<!-- Alt + 回车 -->
<input @keyup.alt.enter="submit" />
<!-- .exact:精确匹配,不能多按其他修饰键 -->
<button @click.ctrl.exact="onlyCtrl">仅 Ctrl,不能带 Shift 等</button>
<button @click.exact="noModifier">只能单独点击,不带任何修饰键</button>
七、修饰符组合与顺序(易错点)
7.1 顺序影响行为
<!-- 先捕获,再判断是否点的是自己 -->
<div @click.capture.self="handler">...</div>
推荐顺序:capture → 其他逻辑修饰符(如 self)→ passive(如有)。
7.2 不能同时用的组合
<!-- 错误:.passive 表示不调用 preventDefault,和 .prevent 矛盾 -->
@scroll.passive.prevent ❌
<!-- 二选一 -->
@scroll.passive ✅ 只优化滚动
@scroll.prevent ✅ 阻止默认滚动
Vue 会在控制台提示这类冲突。
7.3 可以链式使用
<button @click.stop.prevent="handle">点我</button>
<!-- 先阻止冒泡,再阻止默认行为 -->
八、速查表与常见坑
8.1 速查表
| 分类 | 修饰符 | 一句话 |
|---|---|---|
| 事件 | .stop | 阻止冒泡 |
| 事件 | .prevent | 阻止默认行为 |
| 事件 | .self | 仅当 target 是自己时触发 |
| 事件 | .once | 只触发一次 |
| 事件 | .capture | 捕获阶段触发 |
| 事件 | .passive | 不调用 preventDefault |
| v-model | .lazy | change 时更新 |
| v-model | .number | 转为数字 |
| v-model | .trim | 去首尾空格 |
| 按键 | .enter 等 | 按对应键时触发 |
| 系统 | .ctrl / .alt 等 | 需配合修饰键 |
8.2 常见踩坑
-
.passive和.prevent不能一起用
会报错,需要二选一。 -
type="number"仍然是字符串
数字输入记得加v-model.number。 -
弹窗“点蒙层关闭”用
.self
用@click会导致点内容也关闭,用@click.self才只对蒙层生效。 -
修饰符顺序
不同顺序可能带来不同行为,建议按推荐顺序写。 -
Vue 3 不再支持
keyCodes
自定义按键要用e.key判断。
小结
- 事件修饰符:控制冒泡、默认行为、触发次数(
.stop/.prevent/.self/.once等) - v-model 修饰符:控制更新时机和类型(
.lazy/.number/.trim) - 按键 / 鼠标 / 系统修饰符:让键盘、鼠标事件更精确
日常写代码时,先想清楚:
- 要不要阻止冒泡?→
.stop - 要不要阻止默认?→
.prevent - 弹窗点蒙层关?→
.self - 数字输入?→
.number - 需要去空格?→
.trim
希望这篇能帮你把修饰符的“该选谁、为啥选、坑在哪”搞清楚。
学习本就是一场持久战,不需要急着一口吃成胖子。哪怕今天你只记住了一点点,这都是实打实的进步。
后续我还会继续用这种大白话、讲实战方式,带大家扫盲更多前端基础。
关注我,不迷路,咱们把那些曾经模糊的知识点,一个个彻底搞清楚。
如果你觉得这篇内容对你有帮助,不妨点赞+收藏,下次写代码卡壳时,拿出来翻一翻,比搜引擎更靠谱。
我是 Eugene,你的电子学友,我们下一篇干货见~