1. 父子组件通信
父组件向子组件传递数据:通过
props。子组件在props中声明要接收的数据,父组件在使用子组件时通过属性绑定传递数据。子组件向父组件传递数据:通过自定义事件(
$emit)。子组件通过this.$emit('事件名', 数据)触发事件,父组件在使用子组件时通过v-on(或@)监听事件并接收数据。
父传子:通过
props
父组件在子组件标签上绑定属性,子组件通过props接收。<!-- 父组件 --> <child :msg="message"></child> <!-- 子组件 --> props: ['msg']子传父:通过
$emit
子组件触发事件并传递数据,父组件监听事件。<!-- 子组件 --> this.$emit('update', data); <!-- 父组件 --> <child @update="handleUpdate"></child>
2. 兄弟组件通信
EventBus(事件总线)
创建全局 Vue 实例作为事件中心,通过$on和$emit通信。// eventBus.js export default new Vue(); // 组件A eventBus.$emit('event-name', data); // 组件B eventBus.$on('event-name', (data) => { ... });Vuex(推荐中大型项目)
集中管理共享状态,组件通过commit或dispatch修改状态,通过computed获取状态。
3. 跨级组件通信
EventBus(事件总线):创建一个空的Vue实例作为事件中心,通过
$on监听事件,$emit触发事件。适用于任意组件间通信,但要注意在组件销毁时解绑事件,避免内存泄漏。Vuex:状态管理模式,集中式存储管理应用的所有组件的状态。适用于中大型项目,共享状态较多的情况。
provide/inject:祖先组件通过
provide提供数据,后代组件通过inject注入数据。适用于深层次的组件嵌套,但注意它不是响应式的(除非传入一个可响应的对象)。
provide/inject
祖先组件通过provide提供数据,后代组件通过inject注入。<!-- 祖先组件 --> provide() { return { sharedData: this.data }; } <!-- 后代组件 --> inject: ['sharedData']Vuex(同上)
4. 其他方式
$refs:父组件通过
ref给子组件注册引用信息,然后通过this.$refs.子组件ref名访问子组件的属性和方法。适用于直接操作子组件的情况。$parent/$children:通过
$parent访问父组件,$children访问子组件数组(不推荐,因为组件树结构不稳定)。localStorage/sessionStorage:通过浏览器的存储机制,但要注意这是持久化存储,且不是响应式的,需要手动监听变化。
$refs:父组件通过
ref直接访问子组件方法/属性。<child ref="childRef"></child> this.$refs.childRef.method();$attrs/$listeners(Vue 2.4+)
$attrs:接收父组件未在props中声明的属性。$listeners:接收父组件传入的事件监听器。
<!-- 父组件 --> <child :msg="message" @custom-event="handler"></child> <!-- 子组件 --> <grandchild v-bind="$attrs" v-on="$listeners"></grandchild>localStorage/sessionStorage:通过浏览器存储同步数据(非响应式)。
面试关键点总结
核心方式:
父子:
props+$emit兄弟:EventBus / Vuex
跨级:
provide/inject/ Vuex
选择依据:
简单场景:
props/$emit中小型项目:EventBus
大型项目:Vuex
深层级嵌套:
provide/inject
注意事项:
props单向数据流,子组件不可直接修改。EventBus 需手动销毁监听(
beforeDestroy中解绑)。Vuex 遵循严格模式,避免直接修改状态。
Vue 3 补充:
移除
$listeners,改用v-bind="$attrs"透传事件。新增
mitt库替代 EventBus(更轻量)。provide/inject支持响应式(使用ref/reactive)。
回答示例:
“Vue 组件通信主要分父子、兄弟、跨级三种场景。父子通过props和$emit;兄弟用 EventBus 或 Vuex;跨级用provide/inject或 Vuex。简单场景用事件总线,复杂状态管理用 Vuex。注意props单向流和 EventBus 内存泄漏问题。”