进阶基于uniapp/Vue的发布订阅模式实现和快速上手

Posted 帅气的黑桃J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进阶基于uniapp/Vue的发布订阅模式实现和快速上手相关的知识,希望对你有一定的参考价值。

简介

本文将介绍发布订阅者模式、发布订阅者在vue上的运用以及快速上手。

发布订阅模式是什么?举一个例子,在好几年前很多社区都有鲜奶配送的服务,当用户A在他的小区门口的牛奶店付了一个月的鲜奶配送费后,牛奶店就会记录用户A订阅了鲜奶配送服务。于是每天早上,牛奶店都会进行鲜奶配送的服务,如果用户A订阅了鲜奶配送的服务,那么用户A就会在每天早上收到牛奶店配送的牛奶,这就是一个简单的发布订阅者模式,其中用户A是订阅者,牛奶店是发布者,牛奶店会在每天早上发布一个“配送鲜奶”的主题,用户A订阅了该主题,于是用户A就能收到发布者(牛奶店)通过主题(鲜奶配送)发布的信息(鲜奶)。

实际上,发布订阅者设计模式是生活中运用的最广的一种设计模式,如您社交平台上订阅了某个人,在他发布新动态的时候,系统就会通知您您订阅的用户发布了新动态,这就是一种简单的发布订阅者模式。

定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

发布-订阅(Publish/Subscribe)模式的别名包括观察者模式(Observer Pattern)、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

在Uniapp中,如果涉及到一些即时通信和复杂组件下的数据通信时,可以使用配置全局的发布订阅模式来进行topic的广播,让数据间的交互更加灵活。

本文提供了一个方便的全局配置模式,可以快速copy进行调用发布订阅模式,十分方便。

快速上手

先徒手撸一个发布订阅模式,这里我使用的dispatcher作为调度中心来分配发布和订阅之间的关系。

  • 创建一个Dispatcher.js
var dispIns = [];
var dispCbs = [];

function Dispatcher() 
  dispIns.push(this);
  dispCbs.push();


Dispatcher.prototype = 
  // 广播监听
  on(topic, cb) 
    let cbtypes = dispCbs[dispIns.indexOf(this)];
    let cbs = cbtypes[topic] = cbtypes[topic] || [];
    if (!~cbs.indexOf(cb))  cbs.push(cb) 
  ,
  // 关闭监听
  off(topic, cb) 
    let cbtypes = dispCbs[dispIns.indexOf(this)];
    let cbs = cbtypes[topic] = cbtypes[topic] || [];
    let curTypeCbIdx = cbs.indexOf(cb);
    if (~curTypeCbIdx) 
      cbs.splice(curTypeCbIdx, 1);
    
  ,
  // 发布广播
  fire(topic, ...args) 
    let cbtypes = dispCbs[dispIns.indexOf(this)];
    let cbs = cbtypes[topic] = cbtypes[topic] || [];

    for (let i = 0; i < cbs.length; i++) 
      cbs[i].apply(null, args);
    
  
;
module.exports = Dispatcher;
  • 创建一个broadcast.js
var Dispatcher = require("./Dispatcher.js");
module.exports = new Dispatcher();
  • 在main.js进行全局配置
import broadcast from './utils/broadcast'
Vue.prototype.$disp = broadcast

接下来让我们来测试一下

  • 调用方式:发布topic
// 无参发布
this.$disp.fire("topicName")
// 有参发布
this.$disp.fire("topicName",data)
  • 调用方式:监听topic
// 无参监听
this.$disp.on("topicName", function () 
  doSomething()
)
// 有参监听
this.$disp.on("topicName", res => 
  console.log(`[info] res data :$res`)
)

因为已经在全局配置了,因此这个主题在App全局都可以监听到

  • 拿一个Test.vue页面进行测试
<template>
  <view>
    <u-button text='发布' @click="fire"></u-button>

  </view>
</template>
<script>
export default 
  onLoad()
  	//在onLoad的时候或者组件mouted的时候进行监听挂载
    this.$disp.on('myfire',res=>
      console.log(`[disp on] $JSON.stringify(res)`)
    )
  ,
  methods: 
    fire()
      // 发布主题
      this.$disp.fire("myfire",`zeeland's boardcast`)
    
  

</script>
  • 点击发布按钮,运行结果如下:

注意事项

需要注意的是,如果您的主题发布之后再进行主题的监听,那么您将无法监听到当前发布的主题。需要先监听,再发布。

参考资料

对象间的联动——观察者模式

以上是关于进阶基于uniapp/Vue的发布订阅模式实现和快速上手的主要内容,如果未能解决你的问题,请参考以下文章

Redis 进阶 -- 发布与订阅

Redis 进阶 -- 发布与订阅

基于Redis的发布/订阅模式实现者:RedisQ

基于Redis的发布/订阅模式实现者:RedisQ

Spring中的观察者模式(发布订阅模式)(基于SpringBoot实现)

一种基于消息发布-订阅的观察者模式实现