发布订阅模式
参考资料
- https://www.jianshu.com/p/c1be274d94cb
写在前面
订阅发布模式可以用在前端不同组件通讯的问题
正篇
简单来说就是通过在不同组件中引入一个公共类,该类中封装了一个存放key值,和方法队列的数组,以及一个订阅、触发、取消订阅的方法。使用时通过调用订阅方法并传入一个能够修改需要传递值的方法,订阅方法会将方法存放到对应key值的方法队列中。在需要传递值时通过调用触发方法,触发方法会依次调用对应key值的方法队列中的方法,从而对值进行修改。取消订阅的方法则是将对应的方法从方法队列中移除,下面是使用react hook的例子。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 
 | export default {
 
 listenList: {},
 
 listen: function (key, fun) {
 
 if (!this.listenList[key]) {
 this.listenList[key] = [];
 }
 
 this.listenList[key].push(fun);
 },
 
 tigger: function (key, value) {
 let funs = this.listenList[key];
 
 if (!funs || funs.length === 0) {
 return false;
 } else {
 
 funs.forEach((fun) => {
 fun.apply(this, [value]);
 });
 }
 },
 
 remove: function(key, fun){
 let funs = this.listenList[key];
 
 if(!funs){
 return false;
 }
 
 if(!fun){
 fns && (fns.length = 0);
 }else{
 
 for(let i = fns.length - 1; i >=0; i--) {
 if(fns[i] === fun) {
 fns.splice(i, 1)
 }
 }
 }
 },
 };
 
 | 
组件一
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | import React, { useState, useEffect } from 'react';import SubPub from '@/utils/SubPub.js';
 
 export default function App() {
 const [price1, setPrice1] = useState(-1);
 const [price2, setPrice2] = useState(-1);
 
 useEffect(() => {
 
 let changePrice1 = (value) => {
 console.log('comp1:', value);
 setPrice1(value);
 }
 SubPub.listen('price1', changePrice1);
 
 let changePrice2 = (value) => {
 console.log('comp1:', value);
 setPrice2(value);
 }
 SubPub.listen('price2', changePrice2);
 
 
 return ()=>{
 SubPub.remove('price1', changePrice1);
 SubPub.remove('price2', changePrice2);
 }
 }, []);
 return (
 <>
 <h2>This is comp1</h2>
 <h2>{price1}</h2>
 <h2>{price2}</h2>
 <button onClick={() => SubPub.tigger('price1', 1)}>prices1 to 1</button>
 </>
 );
 }
 
 | 
组件二
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | import React, { useState, useEffect } from 'react';import SubPub from '@/utils/SubPub.js';
 
 export default function App() {
 const [price1, setPrice1] = useState(-1);
 const [price2, setPrice2] = useState(-1);
 
 useEffect(() => {
 
 let changePrice1 = (value) => {
 console.log('comp2:', value);
 setPrice1(value);
 }
 SubPub.listen('price1', changePrice1);
 
 let changePrice2 = (value) => {
 console.log('comp2:', value);
 setPrice2(value);
 }
 SubPub.listen('price2', changePrice2);
 
 
 return ()=>{
 SubPub.remove('price1', changePrice1);
 SubPub.remove('price2', changePrice2);
 }
 }, []);
 return (
 <>
 <h2>This is comp2</h2>
 <h2>{price1}</h2>
 <h2>{price2}</h2>
 <button onClick={() => SubPub.tigger('price1', 2)}>prices1 to 2</button>
 </>
 );
 }
 
 | 
应用这两个组件的类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | import React, { useState, useEffect } from 'react';import P1 from '@/pages/page1/index.js';
 import P2 from '@/pages/page2/index.js';
 
 export default function App() {
 return (
 <>
 <P1></P1>
 <P2></P2>
 </>
 );
 }
 
 | 
最终效果
