修饰符是 Vue 提供的指令语法糖,用来声明事件、表单绑定或按键行为的附加规则。
事件修饰符写在事件名后面:
| 修饰符 | 作用 | 原理 |
|---|---|---|
.stop | 阻止事件继续冒泡 | 调用 event.stopPropagation() |
.prevent | 阻止浏览器默认行为 | 调用 event.preventDefault() |
.capture | 在捕获阶段触发监听器 | 注册 capture: true 的监听器 |
.self | 只有事件目标是当前元素时才处理 | 判断 event.target === event.currentTarget |
.once | 最多触发一次 | 注册 once: true 的监听器 |
.passive | 声明监听器不会调用 preventDefault() | 注册 passive: true 的监听器 |
.self 和冒泡.self 判断的是事件的原始目标 target,不是当前正在执行处理器的元素 currentTarget。因此,子元素冒泡上来的事件不会通过 .self。
修饰符会按书写顺序生成处理逻辑,因此顺序可能影响结果:
可以近似理解为:
所以,前者会阻止子元素点击的默认行为,后者只会阻止元素自身点击的默认行为。
.passive与.prevent不应同时使用。前者明确声明不会阻止默认行为,浏览器可能忽略后者并输出警告。
按键修饰符用于键盘事件:
常用按键修饰符:
.enter、.tab、.delete、.esc、.space、.up、.down、.left、.right.ctrl、.alt、.shift、.meta:系统修饰键.exact:要求系统修饰键组合完全匹配按键修饰符本质上是对 KeyboardEvent 的条件判断:Vue 会检查 event.key(或对应按键别名)以及 ctrlKey、altKey、shiftKey、metaKey 等属性,条件满足后才调用处理函数。
| 修饰符 | 作用 | 说明 |
|---|---|---|
.trim | 去除字符串首尾空白 | 写入绑定值前执行 trim() |
.number | 尝试转换为数字 | 通常使用 parseFloat;转换失败时保留原值 |
.lazy | 改用 change 事件同步 | 不再随每次 input 更新,通常在失焦或提交变更时更新 |
.lazy 是事件时机切换,不是防抖,也不会延迟一段固定时间后再执行。
多个修饰符可以组合:
v-model 修饰符(Vue 3)组件上的修饰符不会自动改变值,Vue 会把它们作为 prop 传给组件,由组件决定如何处理:
对于默认的 v-model,子组件接收 modelModifiers:
带参数的 v-model 使用对应名称的修饰符 prop:
组件中接收 firstModifiers,而不是 modelModifiers。
修饰符主要在模板编译阶段被转换成普通 JavaScript 逻辑或原生监听器配置。以事件绑定为例:
可以近似看成:
而 .capture、.once、.passive 等会进一步影响 addEventListener 的 options:
v-model 修饰符则会影响“读取事件值”和“写回响应式数据”的过程:
因此,修饰符不是浏览器 API,也不是独立的运行时魔法,而是 Vue 在编译或运行时帮助我们补上的条件判断、事件调用和监听器配置。
.stop 只影响事件传播,不会阻止链接跳转或表单提交;需要阻止默认行为时使用 .prevent。.prevent 只对有默认行为的事件有意义,不能代替 .stop。.self 不等于“只监听当前元素注册的事件”,它只检查 event.target 是否就是当前元素。.once 是监听器最多执行一次,不是绑定的数据只更新一次。.passive 和 .prevent 语义冲突,不要组合使用。.lazy 不是防抖;需要防抖时应使用防抖函数或专门的 composable。