Vue3组件通信详解:父传子、子传父与兄弟组件通信

前言

在Vue3中,组件之间的通信是构建复杂应用程序的基础。组件通信主要包括父传子、子传父以及兄弟组件通信。本文将详细讲解这三种通信方式,并通过代码示例进行演示。

父传子通信(Props)

父传子通信是Vue中最基本也是最常用的通信方式。父组件通过属性(props)向子组件传递数据。

示例代码

父组件(ParentComponent.vue)

xml 复制代码
vue复制代码
	<template>

	  <div>

	    <child-component :message="parentMessage" :userInfo="userInfo"></child-component>

	  </div>

	</template>

	 

	<script setup>

	import { ref, reactive } from 'vue';

	import ChildComponent from './ChildComponent.vue';

	 

	const parentMessage = ref('Hello from Parent');

	const userInfo = reactive({ name: 'John', age: 30 });

	</script>

子组件(ChildComponent.vue)

xml 复制代码
vue复制代码
	<template>

	  <div>

	    <p>{{ message }}</p>

	    <p>{{ userInfo.name }}</p>

	  </div>

	</template>

	 

	<script setup>

	import { defineProps } from 'vue';

	 

	const props = defineProps({

	  message: String,

	  userInfo: Object,

	});

	</script>

在父组件中,通过v-bind指令(简写为:)将parentMessageuserInfo数据绑定到子组件的messageuserInfo属性上。子组件通过defineProps函数接收这些属性,并在模板中使用。

子传父通信(Emit)

子组件可以通过触发事件的方式向父组件传递数据。Vue3中,子组件使用$emit方法触发事件,父组件通过监听这些事件来接收数据。

示例代码

父组件(ParentComponent.vue)

xml 复制代码
vue复制代码
	<template>

	  <div>

	    <child-component @update="handleUpdate" @delete="handleDelete"></child-component>

	  </div>

	</template>

	 

	<script setup>

	import { ref } from 'vue';

	import ChildComponent from './ChildComponent.vue';

	 

	const handleUpdate = (data) => {

	  console.log('Received from child:', data);

	};

	 

	const handleDelete = () => {

	  // 处理删除逻辑

	};

	</script>

子组件(ChildComponent.vue)

xml 复制代码
vue复制代码
	<template>

	  <div>

	    <button @click="handleClick">更新父组件</button>

	  </div>

	</template>

	 

	<script setup>

	import { defineEmits } from 'vue';

	 

	const emit = defineEmits(['update', 'delete']);

	 

	const handleClick = () => {

	  emit('update', { id: 1, value: 'new value' });

	};

	</script>

在子组件中,通过defineEmits函数定义可以触发的事件。然后,在按钮点击事件中调用emit方法触发update事件,并传递数据给父组件。父组件通过v-on指令(简写为@)监听updatedelete事件,并定义相应的事件处理函数。

兄弟组件通信

兄弟组件之间的通信通常需要通过一个共同父组件来中转,或者使用事件总线(如mitt库)来实现。

1. 通过父组件中转

父组件(ParentComponent.vue)

xml 复制代码
vue复制代码
	<template>

	  <div>

	    <sibling-a @message="handleMessage" />

	    <sibling-b :message="message" />

	  </div>

	</template>

	 

	<script setup>

	import { ref } from 'vue';

	import SiblingA from './SiblingA.vue';

	import SiblingB from './SiblingB.vue';

	 

	const message = ref('');

	 

	const handleMessage = (value) => {

	  message.value = value;

	};

	</script>

兄弟组件A(SiblingA.vue)

xml 复制代码
vue复制代码
	<template>

	  <button @click="sendMessage">发送消息</button>

	</template>

	 

	<script setup>

	import { defineEmits } from 'vue';

	 

	const emit = defineEmits(['message']);

	 

	const sendMessage = () => {

	  emit('message', 'Hello from sibling A');

	};

	</script>

兄弟组件B(SiblingB.vue)

xml 复制代码
vue复制代码
	<template>

	  <p>{{ message }}</p>

	</template>

	 

	<script setup>

	import { defineProps } from 'vue';

	 

	const props = defineProps(['message']);

	</script>

在这个例子中,兄弟组件A通过触发message事件向父组件发送数据,父组件接收到数据后更新自己的状态,并将状态通过props传递给兄弟组件B。

2. 使用事件总线(mitt)

首先,安装mitt库:

markdown 复制代码
bash复制代码
	npm install mitt

然后,在main.js中全局配置事件总线:

javascript 复制代码
javascript复制代码
	import { createApp } from 'vue';

	import mitt from 'mitt';

	import App from './App.vue';

	 

	const app = createApp(App);

	app.config.globalProperties.$bus = mitt();

	app.mount('#app');

组件A(ComponentA.vue)

xml 复制代码
vue复制代码
	<template>

	  <button @click="sendMessage">发送消息</button>

	</template>

	 

	<script setup>

	import { getCurrentInstance } from 'vue';

	 

	const { proxy } = getCurrentInstance();

	 

	const sendMessage = () => {

	  proxy.$bus.emit('myEvent', 'Hello from ComponentA');

	};

	</script>

组件B(ComponentB.vue)

xml 复制代码
vue复制代码
	<script setup>

	import { onMounted, getCurrentInstance } from 'vue';

	 

	const { proxy } = getCurrentInstance();

	 

	onMounted(() => {

	  proxy.$bus.on('myEvent', (message) => {

	    console.log(message); // 输出: "Hello from ComponentA"

	  });

	});

	</script>

在这个例子中,组件A通过事件总线发送消息,组件B通过事件总线接收消息。这种方式不需要通过父组件中转,实现了兄弟组件之间的直接通信。

总结

Vue3中的组件通信方式多种多样,包括父传子(Props)、子传父(Emit)以及兄弟组件通信(通过父组件中转或使用事件总线)。这些通信方式使得组件之间能够更好地协作和共享数据,提高了应用的可维护性和扩展性。通过合理使用这些通信方式,可以构建出复杂而高效的Vue3应用程序。

相关推荐
岳哥i2 小时前
vue鼠标单机复制文本
javascript
jacGJ2 小时前
记录学习--文件读写
java·前端·学习
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于WEB的实验室开放式管理系统的设计与实现为例,包含答辩的问题和答案
前端
幻云20102 小时前
Python深度学习:从筑基到登仙
前端·javascript·vue.js·人工智能·python
我即将远走丶或许也能高飞4 小时前
vuex 和 pinia 的学习使用
开发语言·前端·javascript
钟离墨笺4 小时前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
爱吃泡芙的小白白4 小时前
Vue 3 核心原理与实战:从响应式到企业级应用
前端·javascript·vue.js
卓怡学长5 小时前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
码上成长5 小时前
JavaScript 数组合并性能优化:扩展运算符 vs concat vs 循环 push
开发语言·javascript·ecmascript
老陈聊架构6 小时前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill