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

相关推荐
mldong11 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排12 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby606113 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角14 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!14 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰14 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi15 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen16 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马17 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu17 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss