vue 3 组件事件命名必须统一使用 kebab-case(短横线分隔),因 html 属性不区分大小写,驼峰写法在模板中监听会失效;模板中需写 @user-updated,defineemits 类型声明和 emit 调用也应保持 'user-updated' 格式。

Vue 3 中组件事件命名的关键在于统一使用 kebab-case(短横线分隔),这是官方推荐且最稳妥的实践。
这个规则不是可选项,而是由 HTML 的大小写不敏感特性决定的——浏览器会把 myEvent、myevent、MyEvent 全部转成小写处理,导致驼峰写法在模板中监听时可能失效或难以调试。
事件名在模板中必须用 kebab-case
你在 <template></template> 里用 v-on 或 @ 监听事件时,必须写成短横线形式:
<user-profile></user-profile>
即使子组件内部用 defineEmits 声明的是驼峰名,模板中仍要转成 kebab-case:
// 子组件 const emit = defineEmits()
注意:这里类型声明里的事件名是字符串字面量,直接写 'user-updated',不是 userUpdated。虽然你也可以写 userUpdated 类型,但 Vue 会自动把它映射为 user-updated,容易造成混淆,建议类型声明也保持 kebab-case 字符串。
不要在模板里用驼峰监听事件
下面这些写法是错误或不可靠的:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
<!-- ❌ 错误:HTML 不识别驼峰,监听不到 --> <user-profile></user-profile><!-- ❌ 错误:大小写混乱,易出错 --><user-profile></user-profile>
原因很简单:
- 模板最终被解析为 HTML 属性,而 HTML 属性名不区分大小写;
- Vue 编译器不会对
@userUpdated做自动转换,它会原样查找名为userupdated的事件,而不是user-updated。
emit 调用时也建议用 kebab-case 字符串
虽然 emit('userUpdated') 在 JS 层能运行(Vue 内部做了兼容),但为了和模板监听名完全一致、避免歧义,调用时也应统一用 kebab-case 字符串:
emit('user-updated', user)
emit('profile-deleted')
这样团队成员一眼就能对应上模板里的 @user-updated,排查问题更直接。
特殊情况:需要动态拼接事件名?
如果必须动态生成事件名(比如封装通用 emit 工具函数),确保拼接结果仍是 kebab-case 格式:
function emitWithPrefix(prefix: string, event: string) {
const kebabEvent = `${prefix}-${event.replace(/([A-Z])/g, '-$1').toLowerCase()}`
emit(kebabEvent)
}
// 使用
emitWithPrefix('auth', 'loginSuccess') // → 'auth-login-success'
但这类逻辑应尽量避免,优先用明确、静态的事件名提升可维护性。
事件命名看似小细节,但直接影响父子通信是否稳定、协作是否顺畅。坚持 kebab-case,不妥协,不混用,团队协作就少踩一半坑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









