Vue 组件之间通信方式有哪些
面试速答(30 秒版 TL;DR)
- 父子:
props向下、emit向上(v-model本质也是 props + emit)。 - 跨层:
provide/inject(依赖注入)。 - 兄弟/跨模块:状态管理(Pinia/Vuex)或把状态上提到共同父组件。
- 特殊通道:
slot、attrs、ref(拿子组件实例/暴露方法,谨慎用)。
按“数据流方向”回答更稳
1) 自上而下:props
- 父组件把数据作为
props传给子组件。 - 优点:显式、可追踪、易维护。
2) 自下而上:emit
- 子组件用
emit发事件给父组件。 - 适合:表单输入、按钮点击、通知父组件刷新等。
3) 双向:v-model(语法糖)
- Vue 3:
modelValue+update:modelValue - Vue 2:
value+input(或model自定义)
4) 跨层:provide/inject
- 适合:组件库、主题/配置、表单上下文、依赖注入。
- 注意:它不是“全局状态管理”,更像“局部范围的上下文”。
5) 全局共享:状态管理
- Pinia(Vue 3 推荐)/ Vuex(遗留项目常见)。
- 适合:跨路由、跨组件的大范围共享状态(用户信息、权限、购物车)。
其他方式(说对边界即可)
- slot:父传子结构,子用插槽渲染父提供的内容;也可以用“作用域插槽”把子的数据回传给父的插槽内容。
- $refs / template ref:父直接拿子组件实例/DOM,适合聚焦、滚动、调用少量 imperative API;不适合作为常规数据流。
- 事件总线(EventBus):Vue 2 时代常见,但在大型项目难维护,Vue 3 通常不推荐。
面试加分:选择建议
- 优先:props/emit、状态上提、store。
- 跨层但范围可控:provide/inject。
- 需要“命令式”操作少量 UI:ref。