defineEmits 是 Vue 3 <script setup> 中声明子组件自定义事件的必需方式,需显式列出事件名(如 ['update-name', 'submit-form']),支持类型校验与 IDE 提示,事件名推荐 kebab-case,空数组表示不触发任何事件,配合 emit() 函数调用并严格匹配父组件 @事件名 监听。

在 Vue 3 的 `<script setup>` 语法糖中,`defineEmits` 是声明子组件可触发自定义事件的必需方式。它不是可选的装饰,而是类型安全、IDE 可识别、编译期可校验的关键声明。</script>
必须显式声明事件名
子组件不能随意 `emit('xxx')`,必须先用 `defineEmits` 列出允许触发的事件名,否则 TypeScript 报错,开发工具也无法提示。
- 写法:`const emit = defineEmits(['update-name', 'submit-form', 'close-dialog'])`
- 事件名推荐用短横线格式(kebab-case),比如 update-user,而不是 updateUser —— 因为 HTML 模板中属性名不区分大小写,驼峰会失效
- 支持空数组 `defineEmits([])` 表示不对外发任何事件,适合只接收不反馈的子组件
触发事件要调用 emit 函数
声明后得到的 `emit` 是个函数,直接调用即可向父组件“喊话”:
使用 `@ainative/vue-sdk` 为 Vue 3 应用添加 AI 聊天功能。适用于以下场景:(1) 安装 `@ainative/vue-sdk`,(2) 在 Vue 组件中使用 `useChat` 组合式函数,(3) 提供……
- 无参触发:
emit('close-dialog') - 带一个参数:
emit('update-name', '李四') - 带多个参数:
emit('submit-form', formData, { validate: true })—— 父组件监听函数会收到所有参数,按顺序传入
父组件监听要严格匹配事件名
父组件模板中用 `@事件名` 绑定处理函数,名称必须和 `defineEmits` 中声明的一致(包括连字符、大小写):
立即学习“前端免费学习笔记(深入)”;
- 正确:
<UserCard @update-name="onNameChange" /> - 错误:
<UserCard @updateName="..." />(HTML 中等价于updatename,无法匹配) - 错误:
<UserCard @click="$emit('xxx')" />($emit是子组件内部方法,父组件模板里不能调用)
配合 v-model 实现双向绑定(进阶)
当事件名是 update:xxx 格式时,Vue 会自动关联 `v-model:xxx` 语法糖:
- 子组件声明:
defineEmits(['update:modelValue', 'update:status']) - 父组件使用:
<MyInput v-model="text" v-model:status="active" /> - 触发更新:
emit('update:modelValue', newValue)→ 自动同步 `text`

















