Vue自定义事件名必须用kebab-case,因HTML模板大小写不敏感,@item-added而@itemAdded❌;emit可灵活但建议统一;命名需动词优先、具体明确,如filter-applied,change❌。
Vue 中自定义事件名必须用 kebab-case(短横线分隔),这是由 HTML 模板的大小写不敏感特性决定的,不是风格偏好,而是功能刚需。
父组件在模板里绑定事件时,@ 后面的名字必须全小写、用短横线连接,比如:
@item-added ✅@search-submitted ✅@user-profile-updated ✅@itemAdded ❌(DOM 模板中会被转为 @itemadded,无法匹配)@click ❌(与原生事件冲突,语义模糊)在 defineEmits 或 this.$emit() 中,Vue 支持两种写法:
defineEmits(['item-added', 'form-reset']) —— 推荐,和模板完全一致,无歧义defineEmits(['itemAdded', 'formReset']) —— SFC 中可用,但需注意:Vue 会自动把 itemAdded 映射到 @item-added,前提是父组件监听时仍用短横线['item-added', 'formReset'] 容易导致团队理解偏差事件名不是 ID,而是对“发生了什么”的简洁陈述。读出来应该像一句英文短句:
filter-applied → “a filter was applied” ✅file-upload-error → “a file upload error occurred” ✅tab-changed → “the active tab changed” ✅change ❌(太泛,和原生 input / change 易混淆)updated ❌(没说明谁被更新、怎么更新)如涉及多模块协作,前缀能快速定位上下文,但关键在一致性:
auth-login-success、cart-item-removed ✅(名词结构,统一风格)onUserAdd、handleUpload、uploadDone ❌(混入方法命名习惯,时态/语义不统一)user- 前缀,就不要突然变成 profile: 或 usr-