Vue3实现组件通信的14种方式详解与实战

 更新时间:2025年08月12日 09:36:08   作者:编程随想_Code  
在Vue3中,组件通信仍然是一个非常重要的话题,因为在大多数应用程序中,不同的组件之间需要进行数据传递和交互,在Vue3中,组件通信有多种方式可供选择,本文给大家介绍了Vue3实现组件通信的14种方式,需要的朋友可以参考下

一、父子组件通信

1. props 父传子

适用场景:父组件向子组件传递数据
核心用法defineProps 接收 props

<!-- 父组件 Parent.vue -->
<template>
  <Child :message="parentMsg" />
</template>
<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const parentMsg = ref('Hello from Parent');
</script>

<!-- 子组件 Child.vue -->
<template>
  <div>父组件传递的props: {{ message }}</div>
</template>
<script setup>
const props = defineProps({
  message: String
});
</script>

注意事项

  • 保持单向数据流,子组件不要直接修改 props。
  • 可通过 defineProps 设置类型校验和默认值。

2. defineEmits 子传父

适用场景:子组件向父组件传递数据
核心用法defineEmits 定义自定义事件

<!-- 子组件 Child.vue -->
<template>
  <button @click="sendData">发送数据</button>
</template>
<script setup>
const emit = defineEmits(['update']);
function sendData() {
  emit('update', 'Data from Child');
}
</script>

<!-- 父组件 Parent.vue -->
<template>
  <Child @update="handleUpdate" />
</template>
<script setup>
function handleUpdate(data) {
  console.log('接收到子组件数据:', data);
}
</script>

补充

  • 推荐使用 update:propName 命名规范(如 update:count)。
  • 避免直接传递父组件方法给子组件调用(如 <Child :onUpdate="handleUpdate" />)。

3. $attrs 属性透传

适用场景:透传未声明的属性到子组件
核心用法$attrs 自动继承父组件未声明的属性

<!-- 父组件 Parent.vue -->
<template>
  <Child :customAttr="123" />
</template>

<!-- 子组件 Child.vue -->
<template>
  <div v-attrs="$attrs"></div>
</template>
<script setup>
import { useAttrs } from 'vue';
const attrs = useAttrs();
console.log(attrs.customAttr); // 输出 123
</script>

4. ref + defineExpose

适用场景:父组件调用子组件方法或访问子组件数据
核心用法ref 获取子组件实例,defineExpose 暴露方法/数据

<!-- 父组件 Parent.vue -->
<template>
  <Child ref="childRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>
<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const childRef = ref(null);
function callChildMethod() {
  childRef.value?.childMethod();
}
</script>

<!-- 子组件 Child.vue -->
<script setup>
function childMethod() {
  console.log('子组件方法被调用');
}
defineExpose({ childMethod });
</script>

注意事项

  • 仅在必要时使用(如表单验证),避免过度依赖。

5. v-model 双向绑定

适用场景:实现父子组件双向数据绑定
核心用法modelValue + update:modelValue

<!-- 父组件 Parent.vue -->
<template>
  <Child v-model="value" />
</template>
<script setup>
import { ref } from 'vue';
const value = ref('初始值');
</script>

<!-- 子组件 Child.vue -->
<template>
  <input :value="modelValue" @input="updateValue" />
</template>
<script setup>
const props = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
function updateValue(e) {
  emit('update:modelValue', e.target.value);
}
</script>

二、兄弟组件通信

6. 父组件中转

适用场景:兄弟组件通过父组件共享数据

<!-- 父组件 Parent.vue -->
<template>
  <BrotherA @data-change="handleDataChange" />
  <BrotherB :shared-data="sharedData" />
</template>
<script setup>
import { ref } from 'vue';
const sharedData = ref('');
function handleDataChange(data) {
  sharedData.value = data;
}
</script>

7. mitt 事件总线

适用场景:轻量级解耦通信(无共同父组件)
核心用法mitt 创建事件中心

// eventBus.js
import mitt from 'mitt';
export const emitter = mitt();

// 组件A
<script setup>
import { emitter } from './eventBus.js';
function sendData() {
  emitter.emit('brother-event', { id: 1 });
}
</script>

// 组件B
<script setup>
import { emitter } from './eventBus.js';
emitter.on('brother-event', (data) => {
  console.log('接收到数据:', data);
});
</script>

8. 全局状态管理(Pinia/Vuex)

适用场景:复杂应用中的全局状态共享

// store/counter.js (Pinia)
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: { increment() { this.count++; } }
});

// 组件A
<script setup>
import { useCounterStore } from '@/store/counter';
const store = useCounterStore();
store.increment();
</script>

// 组件B
<script setup>
import { useCounterStore } from '@/store/counter';
const store = useCounterStore();
console.log(store.count);
</script>

三、跨层级通信

9. provide/inject

适用场景:祖孙组件或深层嵌套组件通信

<!-- 父组件 Parent.vue -->
<script setup>
import { provide, ref } from 'vue';
const theme = ref('dark');
provide('theme', theme);
</script>

<!-- 子组件 Child.vue -->
<script setup>
import { inject } from 'vue';
const theme = inject('theme');
console.log('当前主题:', theme.value);
</script>

10. 全局状态管理(Pinia/Vuex)

与兄弟组件通信中的 Pinia 用法一致,适用于跨层级状态共享。

四、其他通信方式

11. 浏览器本地存储(localStorage/sessionStorage)

适用场景:持久化数据共享(如用户偏好设置)

// 存储数据
localStorage.setItem('user', JSON.stringify({ name: '豆豆' }));

// 读取数据
const user = JSON.parse(localStorage.getItem('user'));
console.log(user.name); // 输出 豆豆

12. 全局 window 对象

适用场景:临时跨组件通信(慎用)

12. 全局 window 对象
适用场景:临时跨组件通信(慎用)

13. ES6 模块化(import/export)

适用场景:常量或工具函数共享

// constants.js
export const API_URL = 'https://api.example.com';

// 组件中使用
import { API_URL } from '@/constants';
console.log(API_URL); // 输出 https://api.example.com

14. 作用域插槽(Slot Props)

适用场景:父组件向子组件传递函数或配置对象

<!-- 父组件 Parent.vue -->
<template>
  <Child>
    <template #default="{ config }">
      <div :style="config">{{ config.title }}</div>
    </template>
  </Child>
</template>

<!-- 子组件 Child.vue -->
<script setup>
import { reactive } from 'vue';
const config = reactive({ title: 'Slot Injected Config' });
</script>

五、最佳实践建议

优先选择标准化方案

80% 场景使用 props + emits

复杂场景选择 provide/inject 或状态管理库。

避免过度使用全局状态

仅当数据需要在多组件间共享时使用 Pinia/Vuex。

善用 $attrs

减少子组件 props 定义,实现属性透传。

谨慎操作 ref

仅在必要时直接调用子组件方法,保持组件解耦。

事件命名规范

使用 on[EventName] 格式,如 on:update

六、总结

Vue3 提供了丰富且灵活的组件通信方式,开发者应根据具体场景选择最优方案。以下是常见场景的推荐选择:

场景推荐通信方式
父子通信props + defineEmits
兄弟组件通信mitt 或父组件中转
跨层级通信provide/inject 或 Pinia
全局状态共享Pinia 或 Vuex
临时数据共享localStorage 或 window

掌握这些通信方式后,可以更高效地构建复杂应用。建议将示例代码复制到项目中运行,观察不同方式的数据流向和效果差异。

以上就是Vue3实现组件通信的14种方式详解与实战的详细内容,更多关于Vue3组件通信方式的资料请关注脚本之家其它相关文章!

相关文章

  • vue双向锚点实现过程简易版(scrollIntoView)

    vue双向锚点实现过程简易版(scrollIntoView)

    这篇文章主要介绍了vue双向锚点实现过程简易版(scrollIntoView),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • vue cli 3.0通用打包配置代码,不分一二级目录

    vue cli 3.0通用打包配置代码,不分一二级目录

    这篇文章主要介绍了vue cli 3.0通用打包配置代码,不分一二级目录,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • vue 请求后台数据的实例代码

    vue 请求后台数据的实例代码

    本篇文章主要介绍了vue 请求后台数据的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧、
    2017-06-06
  • Vue Router4路由导航守卫实例全面解析

    Vue Router4路由导航守卫实例全面解析

    这篇文章主要为大家介绍了Vue Router4路由导航守卫实例全面解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • vue-cli3中配置alias和打包加hash值操作

    vue-cli3中配置alias和打包加hash值操作

    这篇文章主要介绍了vue-cli3中配置alias和打包加hash值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • vue 实现上传按钮的样式的两种方法

    vue 实现上传按钮的样式的两种方法

    这篇文章主要介绍了vue 定制上传按钮的样式的两种方法,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • vue 请求后端数据的示例代码

    vue 请求后端数据的示例代码

    在vue中,我们如何通过请求接口来访问后端的数据呢?在这里简单总结了一个小示例,对vue请求后端数据实例代码感兴趣的朋友一起看看吧
    2022-09-09
  • vue日历组件的封装方法

    vue日历组件的封装方法

    这篇文章主要为大家详细介绍了vue封装一个日历组件的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • el-table渲染慢卡顿问题最优解决方案

    el-table渲染慢卡顿问题最优解决方案

    本文主要介绍了el-table渲染慢卡顿问题最优解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Vue3实现Message消息组件示例

    Vue3实现Message消息组件示例

    在大多数 web 产品中,全局的 Message 组件占有较大的使用场景,本文主要介绍了Vue3实现Message消息组件示例,需要的朋友们下面随着小编来一起学习学习吧
    2021-06-06

最新评论