Vue 有哪些常用修饰符?Vue3 中 .native 和 .sync 去哪了?
先理解原理和示例,再练习完整口述与追问。
回答要点
事件修饰符 .stop .prevent .self .once .capture .passive;按键与鼠标修饰符 .enter .esc .ctrl .exact .left;v-model 修饰符 .lazy .number .trim。Vue3 移除了 .native(未在 emits 声明的事件会作为原生监听器落到根元素)和 .sync(改为 v-model:prop),也支持自定义 v-model 修饰符。
原理拆解
修饰符是模板编译期的语法:@click.stop 会被编译成先调用 event.stopPropagation() 再执行处理函数的包装,.passive 则映射为 addEventListener 的 { passive: true }。修饰符可以串联,顺序有意义:@click.prevent.self 阻止所有点击的默认行为,@click.self.prevent 只阻止点击元素自身时的默认行为。
Vue2 中组件上的 @click 只监听组件 emit 的事件,想监听根元素原生事件要加 .native。Vue3 中,未在 emits 选项声明的监听器作为透传属性 $attrs 落到组件根元素,所以不再需要 .native;声明了的事件只按组件事件处理。.sync 被 v-model:title 取代,一个组件可以有多个 v-model。自定义修饰符通过 modelModifiers 或 Vue 3.4 起的 defineModel 读取。
示例与推演
<script setup>
const [title, modifiers] = defineModel('title', {
set(value) { return modifiers.capitalize ? value.charAt(0).toUpperCase() + value.slice(1) : value }
})
</script>
<template><input v-model="title"></template>
<!-- 父组件:<MyInput v-model:title.capitalize="name" /> -->
易错点
.passive 与 .prevent 不能同时使用,passive 监听器中调用 preventDefault 会被忽略;.once 对组件事件同样生效。多根节点组件没有唯一根元素,透传属性要用 v-bind="$attrs" 指定位置,否则会警告。
参考回答可直接练习口述
常用的有事件修饰符 stop、prevent、self、once、capture、passive,按键修饰符如 enter、exact,以及 v-model 的 lazy、number、trim,它们在编译时被转成对应的事件处理包装。Vue3 去掉了 .native,因为没在 emits 声明的事件会作为 attrs 透传到根元素;.sync 改成了 v-model:prop,一个组件可以绑定多个 v-model,还能用 defineModel 实现自定义修饰符。