如何在微前端中实现全局通信

168 阅读1分钟

微前端中Host与Remote的通信

静态数据的全局通信

通过设置全局的对象去存储静态数据,以便在host和remote去共享。

import {Injectable} from '@angular/core';
import _ from 'lodash';

@Injectable({providedIn: 'platform'})

export class DataStoreService {
    sharedData = {};
    
    private _clone(object) { 
        return ({..object }
    };
    
   get data(){
        this.sharedData = this._clone(this.sharedData):
        return this.sharedData;
    }
    
    set data(value: any) {
        throw new Error('do not mutate the " data" directly');
       }

    get(prop: any) {
        const data = this.data;
        return data.hasOwnProperty(prop) ? data[prop] : null;
    }

    set(prop: string, value: any){
        this.sharedData[prop] = value;
        return this.sharedData[prop];
    }

    clear (exceptionkeys?: string[]) {
        if(_.isEmpty(exemptionKeys)) {
            this.sharedData = {};
            return;
        }
        this.shareData = _.pick(this.shareData, exceptionkeys); //. 保留指定属性以对象形式返回
        }
    }

全局数据的实时通信

通过封装RXJS实现全局的实时通信, 首先封装一下通信的service,让其可以在remote和host中可以更好的使用

import { Injectable } from "@angular/core";
import { Subject } from "rxjs";

@Injectable({
  providedIn: "platform", // 跨平台共享,适用于微前端架构
})
export class CommunicationService {

subMap: Map<string, Subject<unknown>> = new Map<string, Subject<unknown>>();

createAction (actionName: string) {
    const actionSub = new Subject<unknown>();
    this.subMap.set(actionName, actionSub);
}

dispatchAction<T>(actionName: string, payload?: T) {
    this.createActionIfNotPresent(actionName);
    this.subMap.get(actionName).next(payload);
 }
 
createEffect<T, U>(actionName: string, effectToRun: (...args: T[]) => U) {
    this.createActionIfNotPresent(actionName);
    this.subMap.get(actionName).subscribe(effectToRun);
}

destroyAction(actionName: string) {
    if (this.subMap.has(actionName)) {
        this.subMap.get(actionName).unsubscribe();
        this.subMap?.delete(actionName);
    }
}

destroyAll(){
    this.subMap?.forEach((sub) => sub?.unsubscribe?.());
    this.subMap?.clear ();
}

private createActionIfNotPresent (actionName: string) {
    if (!this.subMap.has(actionName)) {
      this.createAction(actionName);
    }
}

数据更改的地方如何使用 communication service 去通知监听的地方数据的变更啦~

# 1. 首先使用的地方先provide这个service
xxfunction(){
    const data = 'test';
    this.communicationService.dispatchAction('CustomKey', data)
}

监听数据变更,并执行相对应的操作

 # 1. 首先使用的地方先provide这个service
 ngOnInit(){
  this.communicationService.destroyAction('CustomKey');
  this.communicationService.createEffect('CustomKey', (data: any) => {
    if(data) {
      // if we listen data change we should do some relevant logic in this callback
    }
  })
 }
 
 # 2. 当前组件销毁时记得取消订阅
 ngOnDestroy(){
     this.communicationService.destroyAction('CustomKey');
 }