Vue3组件间通信知识整理——兄弟组件之间通信

能看到Vue3文章的各位,相信eventBus大家都不陌生。eventBus —— 事件总线,作为Vue2.x兄弟组件通信的方案。但在Vue3中,eventBus已经被官方移除,官方推荐的是更为专业的mitt工具。

兄弟组件通信

场景

用户在个人信息页修改了自己的昵称信息,在页面发送请求服务器响应请求后,页面各个组件主动修改各组件中的昵称信息。例子如下图 ⬇
Vue3组件间通信知识整理——兄弟组件之间通信_第1张图片
在图中每一个红色框都代表同一个页面里的一个组件,我们则需要在用户修改昵称之后,同时修改左侧工具栏以及顶部导航栏的昵称数据,这时就可以用mitt工具库。

下载和引入

首先是下载依赖包⬇

npm i mitt --save

然后是引入,引入方式可以有两种⬇

// 第一种是创建一个工具js,不如说mitt.js,哪个组件要用到就引入该文件就好了。
import mitt from 'mitt'
const emitter = mitt()
export default emitter
// 第二种是像Vue2.x一样直接挂载一个全局的变量,不过这种方式官方说谨慎使用不推荐,感觉是维护性、性能方面的问题吧。
import { createApp } from 'vue'
import mitt from 'mitt'
import App from './App.vue'

const app = createApp(App)
const myMitt = mitt()
app.config.globalProperties.$myMitt = myMitt

使用

使用方面的话就和当初的eventBus大同小异了。

//第一种工具函数引入方式

//兄弟组件一(发布事件)
<script setup>
import mitt from '@/utils/mitt'
const emitter = mitt

emitter.on('xxx',(value)=>{
  console.log(value)
})
</script>

//兄弟组件二(订阅事件)
<script setup>
import mitt from '@/utils/mitt'
const emitter = mitt

emitter.emit('xxx','你好!')
</script>
// 第二种全局挂载方式
//兄弟组件一(发布事件)
<script setup>
//setup语法糖写法需要使用getCurrentInstance获取执行上下文,不是语法糖写法好像是setup(props,context)就可以获取到
import { getCurrentInstance } from "vue"

const cxt = getCurrentInstance() //获取 this
const emitter = cxt.appContext.config.globalProperties.$myMitt

emitter.on('xxx',(value)=>{
  console.log(value)
})
</script>

//兄弟组件二(订阅事件)
<script setup>
import { getCurrentInstance } from "vue"

const cxt = getCurrentInstance() //获取 this
const emitter = cxt.appContext.config.globalProperties.$myMitt

emitter.emit('xxx','你好!')
</script>

总结

按我的理解,我觉得无论是eventBus还是mitt它们都是一种订阅发布模式,也就是说这种通信方式是相对无敌的。不单单只是兄弟组件通信,你可以在任何组件on订阅事件行为,在任何组件emit发布事件行为,实现父子通信、父子孙通信等等。但是这种通信方式也是有弊端的,订阅发布模式的实现是一个闭包,统一管理着一个事件对象,如果项目中过度依赖这种通信方式,里面的事件对象就会变得十分之大,长期占用内存。同时你也可以想象一下,发布一个事件行为需要一个事件名及回调函数,项目各种组件都在依赖这种通信方式,各种事件名混淆在一起,项目的代码可读性会变得十分之差。所以说,专业的还得专业的来在一些典型的业务场景下使用mitt通信,才能让mitt工具库发挥它最大的威力!

文章有问题之处还望评论斧正!

更多其他组件间通信文章链接放在下方⬇
Vue3组件间通信知识整理——父组件向子组件传参
Vue3组件间通信知识整理——子组件向父组件传参
Vue3组件间通信知识整理——父组件调用子组件方法

你可能感兴趣的:(javascript,前端,vue.js)