组件间通信(组件间传递数据)
在 Vue.js 中,组件间通信是开发者需要经常处理的任务,特别是在构建具有多层次组件的复杂应用时。根据组件之间的关系和数据流的复杂程度,可以采用不同的通信方式。以下是常用的几种组件间通信方式:
1. 父子组件通信
父组件向子组件传递数据
- Props :父组件可以通过 props 向子组件传递数据。Props 是在子组件中声明的属性。
-
在父组件中使用子组件并传递数据:
javascript<!-- ParentComponent.vue --> <template> <ChildComponent :message="parentMessage" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { parentMessage: 'Hello from Parent' }; } }; </script>
-
在子组件中声明接收 props:
javascript<!-- ChildComponent.vue --> <template> <div>{{ message }}</div> </template> <script> export default { props: ['message'] }; </script>
-
子组件向父组件传递数据
-
事件传递 :子组件通过
$emit
方法发送自定义事件,父组件通过监听这些事件来接收数据。-
在子组件中发射事件:
javascript<!-- ChildComponent.vue --> <template> <button @click="sendMessage">Send to Parent</button> </template> <script> export default { methods: { sendMessage() { this.$emit('messageEvent', 'Hello from Child'); } } }; </script>
-
在父组件中监听事件:
javascript<!-- ParentComponent.vue --> <template> <ChildComponent @messageEvent="receiveMessage" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, methods: { receiveMessage(msg) { console.log(msg); } } }; </script>
-
2. 兄弟组件通信
- 通过共同的父组件:通常通过父组件作为中介进行通信。第一个子组件向父组件发射事件,父组件处理后将数据传递给另一个子组件。
3. 非父子组件通信
-
Event Bus(主要在 Vue 2 中使用):创建一个空的 Vue 实例用作事件总线,通过它来发射和监听事件。
-
设置事件总线:
javascript// event-bus.js import Vue from 'vue'; export const EventBus = new Vue();
-
在组件中使用:
javascript<!-- Sending Component --> <script> import { EventBus } from './event-bus.js'; export default { methods: { sendMessage() { EventBus.$emit('message-event', 'Hello World'); } } }; </script> <!-- Receiving Component --> <script> import { EventBus } from './event-bus.js'; export default { mounted() { EventBus.$on('message-event', (msg) => { console.log(msg); }); } }; </script>
-
-
Vuex:用于全局状态管理,提供一种集中式的状态存储,并允许所有组件访问。适用于大型应用或需要共享状态的多个组件。
- 使用 Vuex 的时候,需要在每个组件中使用
mapState
,mapGetters
,mapMutations
,mapActions
等辅助函数来访问和操作全局状态。
- 使用 Vuex 的时候,需要在每个组件中使用
4. Provide/Inject
- Provide/Inject API :用于祖先组件向所有子孙组件传递数据,而无需逐层传递。
-
在祖先组件中提供数据:
javascript// GrandparentComponent.vue <script> export default { provide() { return { sharedData: 'This is shared data' }; } }; </script>
-
在子孙组件中注入数据:
javascript// AnywhereDeepComponent.vue <template> <div>{{ sharedData }}</div> </template> <script> export default { inject: ['sharedData'] }; </script>
-
每种通信方式都有其适合的场景,根据组件关系和应用复杂度,合理选择可以提高代码的可维护性和可扩展性。
组件间通信(传递数据)
父组件向子组件传递数据
- 父组件可以通过props向子组件传递数据。在子组件中,使用
props
选项来接收 父组件定义的数据。
javascript
// 父组件
<template>
<div class="MineralView-container">
<h1>[MineralView]</h1>
<MineralsTable :testDeliverText="testDeliverText"></MineralsTable>
</div>
</template>
data() {
return{
testDeliverText: 'test'
}
javascript
// 子组件
// 在子组件中,使用`props`选项来接收 父组件定义的数据
<div>
组件间通信: <hr>
this data is from MineralView.vue: {{testDeliverText}}
</div>
props: ['testDeliverText'],
子组件向父组件传递数据 -- 通过event
javascript
<button @click="sendMessage">click, 子组件向父组件传递数据</button>
data() {
return {
title:'Hello from MineralsTable.vue'
};
},
methods: {
// 子组件向父组件传递数据
sendMessage() {
this.$emit('messageEvent', this.title);
},
javascript
<MineralsTable
:testDeliverText="testDeliverText"
@messageEvent="receiveMessage">
</MineralsTable>
<h1>{{testReceiveText}}</h1>
data() {
return{
testDeliverText: 'test',
testReceiveText: 'testReceive'
}
},
methods: {
// @messageEvent="receiveMessage" 父组件监听$emit对应事件(以接收该事件携带的数据)
// 父组件接收 子组件传递来的数据
receiveMessage(msg) {
console.log(msg);
this.testReceiveText = msg
}