defineEmits 简要介绍
📋 一句话概括
defineEmits 是 Vue 3 组合式 API 中定义 组件事件 的 编译时宏,用于 声明组件 可以 触发 哪些事件。
🎯 核心作用
替代 Vue 2 的 emits 选项,在 <script setup> 中声明组件事件。
📝 基本语法
<script setup>
// 定义 emits
const emit = defineEmits<{
(e: '事件名', 参数1, 参数2, ...): void
}>()
// 触发事件
emit('事件名', 参数值)
</script>
🔧 三种写法
1. TypeScript 类型 字面量 写法(推荐) ★
const emit = defineEmits<{
(e: 'submit', data: FormData): void
(e: 'cancel'): void
(e: 'update:value', value: string): void
}>()
2. 运行时声明(JavaScript)
const emit = defineEmits(['submit', 'cancel', 'update:value'])
3. TypeScript 接口式写法 ★
interface Emits {
(e: 'submit', data: any): void
(e: 'cancel'): void
}
const emit = defineEmits<Emits>()
⚡ 主要特点
优点
- ✅ 类型安全:完整的 TypeScript 支持
- ✅ 智能提示:IDE 提供事件名自动补全
- ✅ 参数验证:编译时检查参数类型
- ✅ v-model 支持:支持
update:xxx双向绑定语法
限制
- ❌ 编译时宏:只能在
<script setup>中使用 - ❌ 只读:
emit函数是只读的
🔄 与 Vue 2 对比
| 特性 | Vue 2 (选项式) | Vue 3 (组合式) |
|---|---|---|
| 定义位置 | emits 选项 |
defineEmits 宏 |
| 类型支持 | 有限 | 完整的 TypeScript |
| 语法 | 相对冗长 | 简洁 |
| 事件验证 | 运行时 | 编译时 |
📦 实际示例
<!-- 子组件 Child.vue -->
<script setup lang="ts">
// 定义事件
const emit = defineEmits<{
(e: 'submit', data: { name: string, age: number }): void
(e: 'cancel'): void
(e: 'update:visible', visible: boolean): void
}>()
// 触发事件
const handleSubmit = () => {
emit('submit', { name: '张三', age: 25 })
emit('update:visible', false)
}
const handleCancel = () => {
emit('cancel')
emit('update:visible', false)
}
</script>
<template>
<button @click="handleSubmit">提交</button>
<button @click="handleCancel">取消</button>
</template>
<!-- 父组件使用 -->
<template>
<Child
@submit="handleSubmit"
@cancel="handleCancel"
v-model:visible="modalVisible"
/>
</template>
🎯 v-model 双向绑定
// 子组件定义
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
// 父组件使用
<ChildComponent v-model="value" />
// 等价于
<ChildComponent :modelValue="value" @update:modelValue="value = $event" />
💡 常见使用场景
- 表单提交:
@submit事件传递表单数据 - 模态框控制:
@close、@confirm事件 - 数据变更:
@change、@input事件 - 操作反馈:
@success、@error事件 - 双向绑定:
update:xxx实现 v-model
⚠️ 注意事项
- 事件名使用 kebab-case(HTML 中自动转换)
- 组件内部不能修改
emit函数 - 使用 TypeScript 获得完整类型提示
- 复杂参数建议定义接口类型
🎓 记住这几点
- 只在
<script setup>中使用 - 触发事件用
emit('事件名', 参数) - TypeScript 能提供完整类型检查
- 支持 v-model 双向绑定语法
这就是 defineEmits 的核心要点!它是 Vue 3 组件通信的重要工具,让事件定义更加类型安全和规范。
