vue3兄弟组件之间通信

127 阅读1分钟

1.通过父组件中转

我觉得这是实现兄弟组件通信最简单的方法。

兄弟组件 A

<script setup>
import { defineEmits } from 'vue'

const emit = defineEmits(['updateData'])

const sendDate = () => { 
  emit('updateData','由Child1发送,hello child2')
}
</script>

<template>
  <div class="child-one">
    <h3>兄弟组件A</h3>
    <button @click="sendDate">发送数据</button>
  </div>
</template>

<style scoped>
.child-one {
  width: 100%;
  height: 200px;
  background-color: skyblue;
}
</style>

兄弟组件 B

<script setup>
import { defineProps } from 'vue';

const { data } = defineProps(['data'])
</script>

<template>
  <div class="child-two">
    <h3 class="title">兄弟组件B</h3>
    我是Child2:{{ data }}
  </div>
</template>

<style scoped>
.child-two {
  height: 200px;
  width: 100%;
  background-color: antiquewhite;
}
</style>

父组件

<script setup>
import Child1 from './components/Child1.vue'
import Child2 from './components/Child2.vue'
import{ ref } from 'vue'

const dateForB = ref(null)

const handleUpdate = (data) => {
  dateForB.value = data
}
</script>

<template>
  <div class="father">
    <h3 class="title">父组件</h3>
    <Child1 @update-data="handleUpdate" />
    <Child2 :data="dateForB" />
  </div>
</template>

<style scoped>
.father {
  height: 600px;
  width: 600px;
  background-color: blueviolet;
}
.title {
  color: white;
}
</style>

效果图:

image.png

2.事件总线mitt

理论上,事件总线可以实现任意组件之间的通信。 但是一般多用于兄弟组件之间的通信。

安装mitt

因为vue3原生没有提供事件总线这种方法,所以需要安装mitt来实现事件总线。

pnpm add mitt

然后在src目录下,创建一个文件夹utils:

image.png

import mitt from "mitt"

const EventBus = mitt()

export default EventBus

EventBus有三个经常调用的方法:

image.png

  1. emit:触发事件
  2. on:监听事件
  3. off:清除事件

App.vue组件:

<script setup>
import ChildComponent from "@/components/ChildComponent.vue"
import ChildComponent2 from "@/components/ChildComponent2.vue"
</script>

<template>
  <v-app>
    <ChildComponent />
    <ChildComponent2 />
  </v-app>
</template>

ChildComponent.vue组件:

<script setup>
import {ref} from "vue"
import EventBus from "@/utils/emitter.js"

const child1Car = ref("法拉利")
</script>

<template>
  <div class="bg-purple h-50 w-75 ma-auto">
    <h1 class="text-center">我是子组件1</h1>
    <h2>子组件1的车:{{child1Car}}</h2>

    <!--用EventBus.emit触发事件-->
    <v-btn @click="EventBus.emit('sendCar',child1Car)" class="bg-blue ml-6">点我给兄弟送一台法拉利</v-btn>
  </div>
</template>

ChildComponent2.vue组件:

<script setup>
import { ref,onUnmounted } from "vue"
import EventBus from "@/utils/emitter.js"

const child2Car = ref('')

// 监听事件
EventBus.on('sendCar', (value)=>{
  child2Car.value = value
})

//当组件卸载时,移除监听事件
onUnmounted(()=>{
  EventBus.off('sendCar')
})
</script>

<template>
  <div class="bg-blue h-50 w-75 ma-auto">
    <h1 class="text-center">我是子组件2</h1>
    <h2>组件1给我的车:{{child2Car}}</h2>
  </div>
</template>

效果图

image.png