📚前端面试题速记
Q19

Vue 3 中父组件与子组件如何通信?

速记答案(30 秒)

父→子:props 传数据/函数。子→父:emit 事件。其它:插槽、ref 拿子实例、provide/inject 跨层、全局状态(Pinia)等。

📖 详细讲解

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

父传子用 props;子传父用 emit 事件。其他方式包括:插槽传递内容、ref 获取子组件实例、provide/inject 跨层级传递、全局状态管理如 Pinia、事件总线等。根据场景选择合适的方式。

通信方式全景图

方式 方向 场景 备注
Props 父->子 数据传递 单向数据流,最常用
Emits 子->父 事件通知 配合 v-on 使用
v-model 双向 表单/状态同步 语法糖
Refs 父->子 实例调用 获取子组件属性/方法 (需 expose)
Provide/Inject 祖先->后代 跨层级共享 插件/主题/全局配置
Slots 父->子 内容分发 作用域插槽可子->父传数据
Attrs 父->子 非 Props 属性 class/style/id 自动透传
Pinia 全局 状态管理 跨组件/跨页面复杂状态
Mitt 任意 事件总线 Vue 3 移除了 $on/$off,需引入第三方库

面试要点

  • 掌握各种通信方式的适用场景
  • 理解单向数据流原则
  • 知道如何选择合适的通信方式

💻 代码示例

组件通信方式汇总
<!-- 父组件 -->
<script setup>
import { ref, provide } from 'vue'
import Child from './Child.vue'

// Props 传递
const message = ref('Hello')

// 通过 ref 获取子组件实例
const childRef = ref()

// Provide 跨层传递
provide('theme', 'dark')

// 处理子组件事件
function handleChange(value: string) {
  console.log('子组件传来:', value)
}
</script>

<template>
  <Child
    ref="childRef"
    :message="message"
    @change="handleChange"
  />
</template>

<!-- 子组件 -->
<script setup>
import { inject } from 'vue'

const props = defineProps<{ message: string }>()
const emit = defineEmits<{ change: [value: string] }>()
const theme = inject('theme')
</script>