在 Vue 3 中,组件通信是一个关键的概念,它允许我们在组件之间传递数据和事件。本文将介绍几种常见的 Vue 3 组件通信方法,包括 props
、emits
、provide
和 inject
、事件总线以及 Vuex 状态管理。
1. 使用 props
和 emits
进行父子组件通信
props
传递数据
props
是父组件向子组件传递数据的一种机制。在子组件中,通过定义 props
属性来接收父组件传递的数据。
父组件 (ParentComponent.vue):
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from Parent Component!'
};
}
};
</script>
子组件 (ChildComponent.vue):
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true
}
}
};
</script>
emits
传递事件
子组件可以通过 $emit
方法向父组件发送事件,从而实现从子组件向父组件传递信息。
子组件 (ChildComponent.vue):
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
export default {
emits: ['messageSent'],
methods: {
sendMessage() {
this.$emit('messageSent', 'Hello from Child Component!');
}
}
};
</script>
父组件 (ParentComponent.vue):
<template>
<ChildComponent @messageSent="handleMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleMessage(message) {
console.log(message);
}
}
};
</script>
2. 使用 provide
和 inject
进行祖孙组件通信
provide
和 inject
允许祖父组件和孙组件之间进行通信,而不需要通过中间的父组件传递数据。
祖父组件 (GrandparentComponent.vue):
<template>
<ParentComponent />
</template>
<script>
import ParentComponent from './ParentComponent.vue';
export default {
components: {
ParentComponent
},
provide() {
return {
grandparentMessage: 'Hello from Grandparent Component!'
};
}
};
</script>
孙组件 (GrandchildComponent.vue):
<template>
<div>{{ grandparentMessage }}</div>
</template>
<script>
export default {
inject: ['grandparentMessage']
};
</script>
3. 使用事件总线进行兄弟组件通信
事件总线是一种常见的用于兄弟组件通信的方法,通常使用 Vue 实例作为事件总线。
事件总线 (eventBus.js):
import { reactive } from 'vue';
const eventBus = reactive({});
export default eventBus;
组件 A (ComponentA.vue):
<template>
<button @click="sendMessage">Send Message to Component B</button>
</template>
<script>
import eventBus from './eventBus.js';
export default {
methods: {
sendMessage() {
eventBus.message = 'Hello from Component A!';
}
}
};
</script>
组件 B (ComponentB.vue):
<template>
<div>{{ message }}</div>
</template>
<script>
import { reactive, toRefs } from 'vue';
import eventBus from './eventBus.js';
export default {
setup() {
const state = reactive({
message: ''
});
state.message = eventBus.message;
return {
...toRefs(state)
};
}
};
</script>