Vue 3 30天精进之旅:Day 08 - 组件通信
在Vue 3的开发过程中,组件之间的通信是一个至关重要的概念。理解如何在父子组件、兄弟组件以及通过全局事件总线进行通信,将帮助我们构建更为灵活和可维护的应用。在今天的学习中,我们将探讨以下几个方面:
- 父子组件之间的通信
- 兄弟组件之间的通信
- 非父子组件之间的通信
- 总结与实践
1. 父子组件之间的通信
在Vue中,父子组件之间的通信主要通过 props 和 自定义事件 实现。
使用 Props 传递数据
父组件可以通过 props 将数据传递给子组件。我们来看一个简单的示例:
vue
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent :message="parentMessage" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
data() {
return {
parentMessage: 'Hello from Parent!',
};
},
};
</script>
vue
<!-- ChildComponent.vue -->
<template>
<div>
<p>{
{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true,
},
},
};
</script>
在这个例子中,ParentComponent
将 parentMessage
作为 message
prop 传递给 ChildComponent
,子组件通过 props
接收数据并展示。
使用 Custom Events (自定义事件)
子组件可以通过 $emit
方法向父组件发送消息或事件。例如:
vue
<!-- ChildComponent.vue -->
<template>
<div>
<button @click="sendMessage">Send Message to Parent</button>
</div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('messageFromChild', 'Hello from Child!');
},
},
};
</script>
vue
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent @messageFromChild="receiveMessage" />
<p>{
{ receivedMessage }}</p>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
data() {
return {
receivedMessage: '',
};
},
methods: {
receiveMessage(msg) {
this.receivedMessage = msg;
},
},
};
</script>
在这个例子中,ChildComponent
通过 sendMessage
方法触发自定义事件 messageFromChild
,而 ParentComponent
则在接收到事件后更新了 receivedMessage
。
2. 兄弟组件之间的通信
兄弟组件之间的通信可以通过父组件作为中介来实现。父组件可以将数据作为 props 传递给两个兄弟组件,或者通过事件监听来传递消息。
例如,假设我们有两个兄弟组件 SiblingA
和 SiblingB
,它们需要通信。我们可以在父组件中处理这个逻辑:
vue
<!-- ParentComponent.vue -->
<template>
<div>
<SiblingA @sendMessage="updateMessage" />
<SiblingB :message="sharedMessage" />
</div>
</template>
<script>
import SiblingA from './SiblingA.vue';
import SiblingB from './SiblingB.vue';
export default {
components: {
SiblingA,
SiblingB,
},
data() {
return {
sharedMessage: '',
};
},
methods: {
updateMessage(msg) {
this.sharedMessage = msg;
},
},
};
</script>
SiblingA.vue 触发事件
vue
<!-- SiblingA.vue -->
<template>
<div>
<button @click="sendMessage">Send Message to Sibling B</button>
</div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('sendMessage', 'Hi from Sibling A');
},
},
};
</script>
SiblingB.vue 接收对方的消息
vue
<!-- SiblingB.vue -->
<template>
<div>
<p>{
{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: String,
},
};
</script>
3. 非父子组件之间的通信
对于不直接关联的组件,我们通常可以使用 中央事件总线 或 状态管理工具(如 Vuex 或 Pinia)来进行通信。
使用中央事件总线
创建一个事件总线,允许不同组件通过它进行通信。
javascript
// eventBus.js
import { reactive } from 'vue';
const eventBus = reactive({});
export default eventBus;
然后在组件中使用它发送和接收事件:
javascript
// AnyComponent.vue
import eventBus from './eventBus';
export default {
mounted() {
this.sendMessage();
eventBus.on('my-event', this.handleEvent);
},
methods: {
sendMessage() {
eventBus.dispatch('my-event', 'Hello from AnyComponent');
},
handleEvent(msg) {
console.log(msg);
},
},
};
4. 总结与实践
在今天的学习中,我们深入理解了组件之间的通信方式,包括父子组件的props与自定义事件、兄弟组件的父组件中介方法,以及通过事件总线实现的非父子组件通信。掌握这些通信方式将帮助我们更好地解决实际开发中的问题。
练习
- 尝试改进之前的 Todo 应用,增加新功能,使用组件通信来处理不同组件之间的数据流。
- 设计一个简单的消息系统,让多个组件可以互相发送消息,体验事件总线的工作原理。
在下一天的学习中,我们将关注 组合式API 的使用,继续深入Vue的世界。让我们保持学习热情,明天见!