【进阶】基于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>
  • 点击发布按钮,运行结果如下:
    在这里插入图片描述

注意事项

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

参考资料

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zeeland

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值