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

江湖大侠 -
Vue 之全局事件总线和消息订阅与发布

之前我们实现了子组件向父组件传递数据,很明显,这是不够的,看完这篇博客,无论哪两个组件之间传递和接收数据都没有问题!
全局事件总线(适用于任意组件间通信)
原理:(看图理解)

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

所有组件都可以看到

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')

使用事件总线:

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

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

提供数据:

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 中所有的事件都会被解绑!后果很严重!!!!
消息订阅与发布(适用于任意组件间通信)
原理:

简单理解:
需要数据的组件:订阅消息
提供数据的组件:发布消息
这个相比第一种方法就要麻烦那么一丢丢了,它需要安装 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 里面创建的,不需要再导入包
最后再分享一个方法:

特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

Tags 标签

前端html5vue.js

扩展阅读

加个好友,技术交流

1628738909466805.jpg