Q6
★ ★ ★ ★ ★
Vue 3 中的 emit 是如何实现的?
⚡ 速记答案(30 秒)
子组件调用 emit('event', payload)。组件实例内部维护一个事件名 → 监听函数列表的映射,emit 时按顺序执行这些回调。
📖 详细讲解
标准面试回答(推荐记住)
子组件通过 emit 触发事件,父组件用 v-on 监听。内部实现是组件实例维护一个事件映射表,emit 时查找对应的监听函数列表并依次执行。Vue 3 推荐使用 defineEmits 声明事件,这样可以获得更好的类型支持。
事件触发机制
编译阶段:
父组件模板中的 @change="handler" 会被编译为 props 形式传入子组件:onChange: handler。
运行时:
- 子组件调用
emit('change', val) - Vue 内部将事件名 'change' 转换为 'onChange'
- 在 Props 中查找对应的处理函数
- 如果找到,执行该函数
区别于 Vue 2:
- Vue 3 移除了
$on、$off、$once实例方法 - Event Bus 模式不再官方支持(需引入 mitt 等库)
- 事件处理现在更接近于 Props 回调模式
✅ 面试要点
- •理解 emit 的内部实现原理
- •掌握 defineEmits 的类型声明
- •知道事件命名的最佳实践
💻 代码示例
emit 使用示例
<!-- Child.vue -->
<script setup lang="ts">
// 类型安全的 emit 声明
const emit = defineEmits<{
change: [value: string]
update: [id: number, data: object]
}>()
function handleClick() {
emit('change', 'new value')
}
</script>
<!-- Parent.vue -->
<template>
<Child @change="handleChange" />
</template>
<script setup>
function handleChange(value: string) {
console.log('收到子组件事件:', value)
}
</script>