使用vite从头搭建一个vue3项目(五)非父子组件(兄弟组件)之间传值mitt

7 篇文章 0 订阅

在这里插入图片描述

一、vue2中非父子组件传值方式

在vue2中,非父子组件(兄弟组件)之间传值经常使用 EventBus,被称作事件总线,其实质就是事件的订阅/发布功能。

通常是在 src 目录中单独声明一个文件 EventBus.vue,然后返回一个 vue 实例,因为vue有自己的 API: $on$off$emit,可以实现事件的订阅、发布功能。

// src/EventBus.vue
<script>
import Vue from 'vue';
export default new Vue();
</script>

使用 EventBus
在 home 组件中监听事件。

// home/index.vue
<script>
import EventBus from '@/EventBus.vue'
export default {
  data(){
	return {
	  message: "",
	  date: "",
	}
  },
  mounted(){
    // 监听 getMessage 事件,获取数据
	EventBus.$on('getMessage', getMessageData)
  },
  destroyed(){
    // 取消监听 getMessage 事件
	EventBus.$off('getMessage', getMessageData)
  },
  methods:{
	getMessageData(data){
	  this.message = data.message;
	  this.date = data.date;
    }
  }
}
</script>

在 about 组件中触发事件。

// about/index.vue
<template>
  <el-button @click="handleClick">点击我</el-button>
</template>
<script>
import EventBus from '@/EventBus.vue'
export default {
  methods: {
    handleClick(){
	  // 触发 getMessage 事件,传递数据
	  EventBus.$emit('getMessage', { message:'我的心好冷,我的心好痛', date:'2024-04-18' })
    }
  }
}
</script>

注意,因为 EventBus 为全局唯一,所以事件命名时要注意别重复!

二、vue3中非父子组件传值方式

因为 vue3 中移除了 $on$off 实例方法,所以不再支持 EventBus 这种方式,推荐使用第三方插件 mitt 来实现事件的发布、订阅功能。

1、安装 mitt

npm install mitt

2、定义 emitter

src/utils 目录下创建 emitter.js 文件,emitter 的使用方式与 vue2 中 EventBus 的使用方式相同。

import mitt from 'mitt'

const emitter = mitt()

export default emitter

3、 emitter 的 API

  • emitter.on() 监听事件
  • emitter.off() 取消监听事件
  • emitter.emit() 触发事件
  • emitter.all.clear() 清除所有事件

emitter.all 是一个 new Map() 实例 ,所有的监听事件都会添加到 all 里面,所以会有 clear 方法 。

emitter.all 在 mitt 源码中的定义:

// 调用 mitt() 时可以传入一个监听事件 Map 参数,如果没有,则重新 new Map() 。
export default function mitt (all){
  all = all || new Map();
  return {
	all
  }
}

mitt API 使用方式:

import emitter from '@/utils/emitter'

// 监听单个事件
emitter.on('foo', e => console.log('foo', e) )

// 监听所有事件
emitter.on('*', (type, e) => console.log(type, e) )

// 触发事件
emitter.emit('foo', { a: 'b' })

// 清除所有事件
emitter.all.clear()

// 监听自定义事件
function onFoo() {}
emitter.on('foo', onFoo)   // listen
emitter.off('foo', onFoo)  // unlisten

mitt 第三方包地址:https://www.npmjs.com/package/mitt

4、示例

在 home 组件中定义事件 handleChange,显示弹框提示信息,在 onMounted 生命周期中监听自定义事件。在 about 组件中触发事件 handleChange,并提示信息。

// home/index.vue
<script setup>
import emitter from "@/utils/emitter"
import { ElMessage } from "element-plus"
function handleChange(data) {
  ElMessage.success(data.message)
}
onMounted(() => {
  // 判断,如果不存在 homeChange 事件,则添加监听事件;否则不做任何处理
  if (!emitter.all.get('homeChange')) {
    emitter.on('homeChange', handleChange)
  }
})
// 此处注释掉 onUnmounted,是因为 home 切换为 about 组件时会卸载而执行当前生命周期,导致 emitter 监听事件失效;
// about 组件永远也不会触发 homeChange 事件,因为根本就没有监听,所以要注释掉。
// 当然,正常离开页面时是需要取消监听的,具体问题,具体分析啊。
// onUnmounted(() => {
//   emitter.off('homeChange', handleChange)
// })
</script>
// about/index.vue
<script setup>
import { getMessage } from '@/api/about'
import emitter from "@/utils/emitter"
const message = ref("")

onMounted(() => {
  handleClick();
})

function handleClick() {
  getMessage().then(res => {
    const { content } = res;
    message.value = content;
    // 触发 homeChange 事件并传值
    emitter.emit('homeChange', { message: content })
  })
}
</script>

效果:
在这里插入图片描述

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值