ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue 之全局事件总线和消息订阅与发布

2021-12-14 10:32:21  阅读:190  来源: 互联网

标签:Vue bus 总线 事件 组件 全局 接收数据 hello


之前我们实现了子组件向父组件传递数据,很明显,这是不够的,看完这篇博客,无论哪两个组件之间传递和接收数据都没有问题!

全局事件总线(适用于任意组件间通信) 原理:(看图理解)

1.png

主要就是通过往 x 身上放事件,然后事件的回调要放在想要获取数据的组件身上,谁要传数据就调用 x 身上对应的事件并往里面存数据就可以了,相当于一个中间商(哎,不得不说,它一出生就被利用了)

当然不是谁都能但此大任的,x 需要具备两个条件:

  1. 所有组件都可以看到

  2. x 身上有 on、on 、on、off 、$emit 方法

统一给 x 命名为 $bus

我们将其定义在 main.js 文件中,创建在 vm 的实例对象身上,因为 vm 实例对象只有一个

创建全局事件总线有两种方法:

1、

const Demo = Vue.extend({})

const d = new Demo()

Vue.prototype.$bus = d

(定义在创建 Vue 的外面)

2、

 new Vue({

    ......
    
      beforeCreate(){
      Vue.prototype.$bus = this //安装全局事件总线, $bus 就是当前应用的 vm

   },

})
复制代码
    

    new Vue({

    render: h => h(App),
  
    beforeCreate(){
  
    Vue.prototype.$bus = this  //安装全局事件总线
    }
  
    }).$mount('#app')
复制代码

使用事件总线:

  1. 接收数据:A 组件想接收数据,则在 A 组件中给 $bus 绑定自定义事件,事件的回调留在 A 组件自身

mounted() { //或者后面指向的是一个方法,方法在 methods 里面定义 //在全局事件总线 bus中绑定一个hello事件,后面的回调是箭头函数,用于接收数据this.bus 中绑定一个 hello 事件,后面的回调是箭头函数,用于接收数据 this.bus中绑定一个hello事件,后面的回调是箭头函数,用于接收数据this.bus.$on("hello", (value) => { console.log("我获取到了数据", value); }); },

  1. 提供数据:

methods: { sentMyName(){ //在该方法中触发 hello 这个事件,把数据传过去 this.bus.bus.bus.emit('hello',this.myName) } }, 用这个方法的好处就是!我们就不需要再在标签里绑定自定义事件了,直接把事件在 $bus 里创建,再在要传数据的地方调用它就可以了!

当然还有个注意点,如果某个事件或绑定事件的组件你不用了,那要养成随时解绑的好习惯!不要占着空间不用,会导致空间浪费从而出现卡顿

最好在 beforeDestroy 钩子中,用 $off 去解绑当前组件所用到的事件

在绑定事件的组件中解绑(即需要数据的组件)

beforeDestroy() { //解绑 bus中名为hello的事件this.bus 中 名为 hello 的事件 this.bus中名为hello的事件this.bus.off("hello"); }, 切记!this.bus.off()里面一定要写要解绑的事件,不然off() 里面一定要写要解绑的事件,不然 off()里面一定要写要解绑的事件,不然bus 中所有的事件都会被解绑!后果很严重!!!!

消息订阅与发布(适用于任意组件间通信) 原理:

2.png

简单理解:

需要数据的组件:订阅消息 提供数据的组件:发布消息

这个相比第一种方法就要麻烦那么一丢丢了,它需要安装 pubsub,我们打开 VScode 的控制台,输入 npm i pubsub-js,进行安装

在传数据和接收数据的组件中都要通过 import pubsub from 'pubsub-js' 引入这个文件

然后就可以开始使用了

接收数据:A 组件想接收数据,则在 A 组件中订阅消息,订阅的回调留在 A 组件自身

this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
  console.log('我接收到数据了',data);
})
复制代码

这里有一个注意点,那就是回调函数的第一个参数 msgName,代表的是 hello,即订阅的消息名,这个必须要写,因为默认第一个参数就是消息名,第二个参数才是数据,前端培训所以不管如何,第一个要占个位,你可以给它取个名字,或者用下划线 _ 占位

提供数据:

methods: { sentMyName(){ pubsub.publish('hello',this.myName) } }, 当然如果订阅的消息不用了,也要将其删除,不能占用空间,但是删除订阅消息不是用 $off ,而是 publish.unsubscribe(this.pubId),其中 this.pubId 是每个消息创建的时候都会有一个 id,就像定时器一样,我们删除就删除它对应的 id 号就可以了

beforeDestroy() { pubsub.unsubscribe(this.pubId) }, 对比两者我们用的更多的是前者,因为它是 Vm 里面创建的,不需要再导入包

最后再分享一个方法:

bbfff49165ad4d23baf60b9ef637d64f.png

 

标签:Vue,bus,总线,事件,组件,全局,接收数据,hello
来源: https://www.cnblogs.com/msjhw/p/15686610.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有