Vu3 跨组件通讯

通过父组件传递

这是最常见的跨组件通信方式之一,适用于兄弟组件或跨级组件之间的通信。通过父组件作为中介来传递数据。

示例
  1. 父组件(ParentComponent.vue)
1<template>
2  <div>
3    <child-a @send-message="handleMessage" />
4    <child-b :message="message" />
5    <p>{{ message }}</p>
6  </div>
7</template>
8
9<script setup>
10import { ref } from 'vue';
11import ChildA from './ChildA.vue';
12import ChildB from './ChildB.vue';
13
14const message = ref('');
15
16const handleMessage = (data) => {
17  message.value = data;
18};
19</script>
  1. 子组件 A(ChildA.vue)
1<template>
2  <button @click="sendMessage">发送消息</button>
3</template>
4
5<script setup>
6const emit = defineEmits(['send-message']);
7
8const sendMessage = () => {
9  emit('send-message', '这是来自 ChildA 的消息');
10};
11</script>
  1. 子组件 B(ChildB.vue)

深色版本

1<template>
2  <p>{{ message }}</p>
3</template>
4
5<script setup>
  defineProps({
7  message: String
8});
9</script>

2. 使用 Composition API 和 Refs

Vue 3 引入了 Composition API,使得跨组件通信更加灵活。

示例
  1. 父组件(ParentComponent.vue)
1<template>
2  <div>
3    <child-a @send-message="handleMessage" />
4    <child-b :message="message" />
5    <p>{{ message }}</p>
6  </div>
7</template>
8
9<script setup>
10import { ref } from 'vue';
11import ChildA from './ChildA.vue';
12import ChildB from './ChildB.vue';
13
14const message = ref('');
15
16const handleMessage = (data) => {
17  message.value = data;
18};
19</script>
  1. 子组件 A(ChildA.vue)
1<template>
2  <button @click="sendMessage">发送消息</button>
3</template>
4
5<script setup>
6const emit = defineEmits(['send-message']);
7
8const sendMessage = () => {
9  emit('send-message', '这是来自 ChildA 的消息');
10};
11</script>
  1. 子组件 B(ChildB.vue)
1<template>
2  <p>{{ message }}</p>
3</template>
4
5<script setup>
6defineProps({
7  message: String
8});
9</script>

3. 使用 Vuex

Vuex 是 Vue.js 的官方状态管理库,适合管理全局状态,适用于大型应用或需要多个组件共享状态的情况。

示例
  1. 安装 Vuex
1npm install vuex --save
  1. 创建 Vuex store
1import { createPinia } from 'pinia';
2import { defineStore } from 'pinia';
3
4const pinia = createPinia();
5
6const useMainStore = defineStore('main', {
7  state: () => ({
8    message: ''
9  }),
10  actions: {
11    setMessage(message) {
12      this.message = message;
13    }
14  },
15  getters: {
16    getMessage: (state) => state.message
17  }
18});
19
20export { pinia, useMainStore };
  1. 主入口文件(main.js 或 main.ts)
1import { createApp } from 'vue';
2import App from './App.vue';
3import { pinia } from './store';
4
5const app = createApp(App);
6app.use(pinia);
7app.mount('#app');
  1. 组件中使用 Vuex
1<template>
2  <div>
3    <p>{{ message }}</p>
4    <button @click="sendMessage">发送消息</button>
5  </div>
6</template>
7
8<script setup>
9import { useMainStore } from './store';
10
11const store = useMainStore();
12
13const sendMessage = () => {
14  store.setMessage('这是来自组件的消息');
15};
16</script>

4. 使用事件总线(Event Bus)

事件总线是一种轻量级的跨组件通信方式,适用于需要跨组件通信但又不想引入 Vuex 的场景。

示例
  1. 创建事件总线
1import { createApp } from 'vue';
2
3const app = createApp({});
4export const EventBus = app.config.globalProperties;
  1. 子组件 A(ChildA.vue)
1<template>
2  <button @click="sendMessage">发送消息</button>
3</template>
4
5<script setup>
6import { EventBus } from '../eventBus';
7
8const sendMessage = () => {
9  EventBus.$emit('message-event', '这是来自 ChildA 的消息');
10};
11</script>
  1. 子组件 B(ChildB.vue)
1<template>
2  <p>{{ message }}</p>
3</template>
4
5<script setup>
6import { EventBus } from '../eventBus';
7
8const message = ref('');
9
10watchEffect(() => {
11  EventBus.$on('message-event', (data) => {
12    message.value = data;
13  });
14
15  onBeforeUnmount(() => {
16    EventBus.$off('message-event', (data) => {
17      message.value = data;
18    });
19  });
20});
21</script>

5. 使用全局事件监听器

通过将事件监听器挂载到 Vue.prototype 上来实现全局事件监听。在 Vue 3 中,可以使用全局的 app.config.globalProperties

示例
  1. 主入口文件(main.js 或 main.ts)
1import { createApp } from 'vue';
2import App from './App.vue';
3
4const app = createApp(App);
5
6app.config.globalProperties.$eventBus = new EventTarget();
7
8app.mount('#app');
  1. 子组件 A(ChildA.vue)
1<template>
2  <button @click="sendMessage">发送消息</button>
3</template>
4
5<script setup>
6import { onMounted, onUnmounted } from 'vue';
7import { $eventBus } from '../main';
8
9const sendMessage = () => {
10  $eventBus.dispatchEvent(new CustomEvent('message-event', { detail: '这是来自 ChildA 的消息' }));
11};
12
13onMounted(() => {
14  $eventBus.addEventListener('message-event', (event) => {
15    console.log(event.detail);
16  });
17});
18
19onUnmounted(() => {
20  $eventBus.removeEventListener('message-event', (event) => {
21    console.log(event.detail);
22  });
23});
24</script>
  1. 子组件 B(ChildB.vue)
1<template>
2  <p>{{ message }}</p>
3</template>
4
5<script setup>
6import { ref, onMounted, onUnmounted } from 'vue';
7import { $eventBus } from '../main';
8
9const message = ref('');
10
11onMounted(() => {
12  $eventBus.addEventListener('message-event', (event) => {
13    message.value = event.detail;
14  });
15});
16
17onUnmounted(() => {
18  $eventBus.removeEventListener('message-event', (event) => {
19    message.value = event.detail;
20  });
21});
22</script>

总结

以上是 Vue 3 中几种常见的跨组件通信方式。选择哪种方式取决于你的具体需求:

  • 通过父组件传递:适用于兄弟组件或跨级组件之间的简单通信。
  • 使用 Composition API 和 Refs:利用 Vue 3 的新特性进行灵活的数据管理和通信。
  • 使用 Vuex:适用于需要全局状态管理的应用,适合大型应用或多个组件共享状态的场景。
  • 使用事件总线(Event Bus):适用于轻量级的跨组件通信,不需要引入 Vuex 的场景。
  • 使用全局事件监听器:通过全局的 app.config.globalProperties 挂载事件监听器,适用于简单场景。
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值