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

相关推荐
记得早睡~几秒前
leetcode654-最大二叉树
javascript·数据结构·算法·leetcode
zeijiershuai4 分钟前
Vue框架
前端·javascript·vue.js
vvilkim6 分钟前
使用 JavaScript 和 HTML5 实现强大的表单验证
开发语言·javascript·html5
写完这行代码打球去6 分钟前
没有与此调用匹配的重载
前端·javascript·vue.js
华科云商xiao徐7 分钟前
使用CPR库编写的爬虫程序
前端
狂炫一碗大米饭9 分钟前
Event Loop事件循环机制,那是什么事件?又是怎么循环呢?
前端·javascript·面试
IT、木易11 分钟前
大白话Vue Router 中路由守卫(全局守卫、路由独享守卫、组件内守卫)的种类及应用场景
前端·javascript·vue.js
用户633263128199911 分钟前
Kotlin协程:Continuation 和 suspend 函数的编译后逻辑
javascript
顾林海11 分钟前
JavaScript 变量与常量全面解析
前端·javascript
程序员小续11 分钟前
React 组件库:跨版本兼容的解决方案!
前端·react.js·面试