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应用程序。

相关推荐
亿元程序员几秒前
箭头游戏那么火,搞个3D的可以吗?我:这不是3年前的游戏了吗?
前端
IT_陈寒2 分钟前
SpringBoot里的这个坑差点让我加班到天亮
前端·人工智能·后端
巫山老妖5 分钟前
大模型工程三驾马车:Prompt Engineering、Context Engineering 与 Harness Engineering 深度解析
前端
Cobyte10 分钟前
4.响应式系统基础:从发布订阅模式的角度理解 Vue3 的数据响应式原理
前端·javascript·vue.js
晓得迷路了12 分钟前
栗子前端技术周刊第 124 期 - ESLint v10.2.0、React Native 0.85、Node.js 25.9.0...
前端·javascript·eslint
星空椰21 分钟前
JavaScript基础:运算符和流程控制
开发语言·javascript·ecmascript
半个俗人29 分钟前
fiddler的基础使用
前端·测试工具·fiddler
a11177631 分钟前
变电站数字孪生大屏ThreeJS 开源项目
前端·信息可视化·开源·html
恋猫de小郭32 分钟前
AI 的公开测评得分都在作弊,就像泡面的封面,一切以实物为准
前端·人工智能·ai编程
禅思院34 分钟前
使用 VueUse 构建一个支持暂停/重置的 CountUp 组件
前端·vue.js·架构