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>