概念
什么是发布者-订阅者模式?
举个通俗易懂的例子:微博,大家都用过,我在微博上关注了某个明星,当这个明星发布了动态时,微博会通知我,我关注的这个明星发布了一条动态。
这种模式其实就是发布者-订阅者模式,在发布者-订阅者模式中,发布者和订阅者并不会产生联系,而是通过中间介质来桥接两者。就像我和我关注的这个明星并不会产生联系,而是通过微博这个中间层来将明星发布的动态推送给我。我们也可以称这个中间介质为调度中心或消息代理。
用过vue的朋友都知道,在vue2.0中,要实现兄弟组件间的通信,有一种方式是通过EventBus的方式去实现。
但在react和小程序中,要想实现兄弟组件间的通信,就没有这种方式,但是就像本文标题所说,我们可以用发布者-订阅者模式去实现。
实现
class EventBus {
constructor(){
this.handleMap = new Map() // 调度中心
}
// 发布者
emit = (type, params) => {
if(this.handleMap.has(type)){
this.handleMap.get(type).forEach(callback => {
callback(params)
});
}
}
// 订阅者
on = (type, callback) => {
if(!(callback instanceof Function)){
throw new Error('callback is not a function') // callback必须是可执行函数
}
if(!this.handleMap.has(type)){
this.handleMap.set(type, [])
}
this.handleMap.get(type).push(callback)
}
}
export default new EventBus()
项目中使用
父组件
import React from "react";
import CompA from "./CompA";
import CompB from "./CompB";
export default function App() {
return (
<div>
<CompA />
<CompB />
</div>
);
}
组件A
import React from "react";
import eventBus from "./eventBus";
class CompA extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: ""
};
}
componentDidMount() {
eventBus.on("test", (msg) => {
this.setState({ msg });
});
}
render() {
return <div>{this.state.msg}</div>;
}
}
export default CompA;
组件B
import React from "react";
import eventBus from "./eventBus";
class CompA extends React.Component {
sendMsg = () => {
eventBus.emit("test", "你好,兄弟!");
};
render() {
return <button onClick={this.sendMsg}>发送信息</button>;
}
}
export default CompA;
效果预览:https://codesandbox.io/s/wizardly-flower-dx1sz?file=/src/App.js