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指令(简写为:)将parentMessage和userInfo数据绑定到子组件的message和userInfo属性上。子组件通过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指令(简写为@)监听update和delete事件,并定义相应的事件处理函数。

兄弟组件通信

兄弟组件之间的通信通常需要通过一个共同父组件来中转,或者使用事件总线(如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应用程序。

相关推荐
itmigrate3 小时前
前端项目里,Object.is 并不是 === 的平替
前端
小大宇4 小时前
Vue知识点6-computed计算属性
前端·javascript·vue.js
程序员海军5 小时前
尤雨溪 : Vue 4 已经在规划中了!
前端·javascript·vue.js
2601_949970695 小时前
HumanizeDuration 跨端三方库仓颉适配全流程
前端·javascript·flutter
风骏时光牛马7 小时前
后端服务接口开发与性能优化
前端
kyriewen7 小时前
我让 4 个 AI 互相 review 代码,最温柔的那个下手最狠
前端·程序员·ai编程
计算机魔术师7 小时前
493家公司白砸AI钱?Apollo这组数据戳破了幻觉
前端
IT_陈寒7 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
天外飞雨道沧桑8 小时前
我在浏览器里练了一个 792 参数的大模型,它学会了补全 JavaScript
开发语言·javascript·ai·ecmascript·ai编程
柳杉8 小时前
用 Codex 完成智慧高速 3D 可视化大屏,从 18 张行业设计稿到可交互的运行监测中心
前端·ai编程·数据可视化