📚前端面试题速记
Q6

Vue 3 中的 emit 是如何实现的?

速记答案(30 秒)

子组件调用 emit('event', payload)。组件实例内部维护一个事件名 → 监听函数列表的映射,emit 时按顺序执行这些回调。

📖 详细讲解

标准面试回答(推荐记住)

子组件通过 emit 触发事件,父组件用 v-on 监听。内部实现是组件实例维护一个事件映射表,emit 时查找对应的监听函数列表并依次执行。Vue 3 推荐使用 defineEmits 声明事件,这样可以获得更好的类型支持。

事件触发机制

编译阶段:
父组件模板中的 @change="handler" 会被编译为 props 形式传入子组件:onChange: handler

运行时:

  1. 子组件调用 emit('change', val)
  2. Vue 内部将事件名 'change' 转换为 'onChange'
  3. 在 Props 中查找对应的处理函数
  4. 如果找到,执行该函数

区别于 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>