Vue自定义事件必须用kebab-case命名且避开原生事件名,如user-created;禁用userCreated、click等;推荐加业务前缀如form:validated;setup中可用safeEmit校验。

Vue.js 中通过 emit 触发自定义事件时,命名不规范容易与原生 DOM 事件(如 click、input、change)冲突,导致行为异常或调试困难。核心原则是:**自定义事件名必须语义清晰、避免与原生事件同名,并统一使用 kebab-case(短横线分隔)格式**。
自定义事件必须用 kebab-case 命名
Vue 官方明确要求:自定义事件名在模板中监听时,会自动转为小写(HTML 不区分大小写),因此推荐始终使用短横线格式,避免大小写混淆或驼峰写法被忽略。
- ✅ 推荐:
user-created、form-submitted、item-removed - ❌ 避免:
userCreated(模板中@userCreated实际匹配不到)、click(覆盖原生 click)
严格避开原生 DOM 事件名
即使加了前缀,也建议彻底绕开所有常见原生事件关键词,因为 Vue 在底层可能复用原生事件机制(尤其在 v-model 或内置组件中)。冲突会引发意外冒泡、默认行为抑制或事件丢失。
- ⚠️ 高危原生事件名:
click、input、change、submit、focus、blur、keydown、scroll - ✅ 安全替代方案:
on-user-click→ 改为user-selected;on-input→ 改为search-query-updated
统一加业务/组件前缀增强可读性
在中大型项目中,为避免跨组件事件名重复或歧义,建议在事件名前加上模块或组件标识,形成“作用域化”命名。
立即学习“前端免费学习笔记(深入)”;
- 例如表单组件:
form:validated、form:reset-requested - 例如用户卡片:
user-card:avatar-uploaded、user-card:profile-edited - 注意:冒号不是必须语法,仅作语义分隔;仍需保持整体为 kebab-case,如
user-card-avatar-uploaded同样有效
在 setup 中 emit 时做校验(可选但推荐)
可在 setup 函数中封装一个带校验的 emit 工具函数,运行时提示潜在冲突:
const safeEmit = (event, ...args) => {
const banned = ['click', 'input', 'change', 'submit', 'focus', 'blur'];
if (banned.includes(event)) {
console.warn(`[Vue Emit Warning] Avoid native event name: "${event}"`);
}
emit(event, ...args);
};
调用时用 safeEmit('user-logged-in') 替代直接 emit,便于早期发现风险。


















