Vue CLI 系列之(十三)消息订阅与发布
消息订阅与发布【pubsub】
1. 理解消息订阅与发布
2. 原理图
通过报纸的订阅与发布来理解就是:A去C那订阅了报纸demo,并说明了自己的住址test,由于test是定义在A中的,而A又把test的引用提供出来了,这样C只要一调用test,自动就来到了A这,也就找到了A住的地儿,C发布test报纸时携带的内容666就是报纸的内容,只要一发布,就送到了A这,也就完成了一次订阅与发布
3. 具体实现【pubsub-js】
消息订阅与发布仅仅是一种思想,pubsub-js是这种思想的一种实现
原生js不能轻松实现订阅与发布,需要借助第三方库pubsub-js【含义:publish、subscribe】,可实现在任意框架【Angular、React、Vue等】中实现消息的订阅与发布
3.1 使用
//接收数据的组件一般在mounted钩子中进行消息的订阅
mounted() {
// 使用subscribe()这个API进行消息的订阅,给出消息名hello和回调,只要有人发布hello消息,该回调就执行
// 回调能够接收到发布消息的人传递过来的数据,回调能接收两个参数,分别是消息名msgName,数据data
// 该API有一个返回值,每次订阅消息,都会返回订阅的消息的ID,每个ID的值都是不同的,用于取消订阅该消息,可将这个id放到组件实例对象vc身上,取消订阅时从vc身上取即可
this.pubId = pubsub.subscribe('hello',function(msgName,data){
console.log('有人发布了hello消息!',msgName,data)
})
},
beforeDestroy() {
// 订阅消息的组件在beforeDestroy钩子中要取消订阅的消息
// 使用unsubscribe()这个API进行消息的取消订阅,需要传入订阅的消息的ID
// 消息的取消订阅思想同定时器,通过id进行取消
pubsub.unsubscribe(this.pubId)
}
//发送数据的组件一般提供发布消息的方法,在不同的时机调用该方法,就能实现不同时机发布消息,进行数据的传递
methods: {
sendStudentName(){
// 使用publish()这个API进行消息的发布,给出发布的消息名,给出消息内容,也就是要传递的数据
pubsub.publish('hello',666)
}
}
3.2 保证订阅消息的回调中的this是组件实例对象的几种写法
pubsub配合Vue使用时订阅消息的回调如果写成普通函数的形式,函数中的this是undefined,由于接收到的消息一般会更新到data中,所以获取到data中的数据就尤为重要,只有this是vc,才能够获取到data中的数据,通过以下几种方式,就能够使得this是vc。
-
直接写成箭头函数
this.pubId = pubsub.subscribe('hello',(msgName,data)=>{ // this就是vc console.log(this) console.log('有人发布了hello消息!',msgName,data) })
-
写成回调函数的引用
// methods中定义好回调 methods:{ publish(msgName,data){ console.log(this) console.log('有人发布了hello消息!',msgName,data) } } mounted() { // 订阅消息时传入回调引用 this.pubId = pubsub.subscribe('hello',this.publish) }
4. 总结
-
一种组件间通信的方式,适用于任意组件间通信。
-
使用步骤:
-
安装pubsub:
npm i pubsub-js
-
引入:
import pubsub from 'pubsub-js'
pubsub是一个对象
-
接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){ demo(data){......} } ...... mounted() { this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息 }
-
提供数据:
pubsub.publish('xxx',数据)
-
最好在beforeDestroy钩子中,用
pubsub.unsubscribe(pid)
去 取消订阅。 -
消息订阅与发布并不常用,相当于代替了全局事件总线中x的角色
-
有消息的订阅与发布操作产生时,Vue开发者工具的事件窗口是看不到的
-
由于订阅消息的组件的回调会收到两个参数,消息名和数据,而消息名我们一般不常用,但消息名又作为第一个参数是不得不写的,否则我们就用不了第二个参数,所以通常用"_"进行占位
// 回调函数 del(_,id){ console.log('del接收到的是:',id) let findedTodo = this.todoList.findIndex((item, index)=>{ return item.id === id }) console.log(findedTodo) this.todoList.splice(findedTodo, 1) }
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本