0.1.1 • Published 3 years ago
micro-shared v0.1.1
⚡一个用于微前端的通信模块
micro-shared以redux
为核心,采用发布-订阅模式
进行封装,实现应用间通信数据上的响应式
,并在代码结构上实现模块化
,使用上编写方式及api类似vuex,上手难度低, 并可适用多框架
(如vue、react)
代码: github or gitee 文档: ⚡qiankun微前端中的应用通信(四)-上手micro-shared及原理解析
安装
yarn add micro-shared
在项目中使用
- 首先在主应用里创建pool文件夹
@/pool
pool
├── index.ts
└── modules
├── locale.ts
└── user.ts
- 然后开始编写user.ts
import { Mutation } from 'micro-shared';
interface UserInfo {
username: string,
}
interface State {
userinfo?: UserInfo | Record<string, never>
}
const state:State = {
userinfo: {},
};
const reducer = (userState: State = state, mutation: Mutation): State => {
switch (mutation.type) {
case 'SET_USERINFO': return {
...userState,
userinfo: mutation.payload,
}; break;
default: return userState;
}
};
const action = {
getUserinfo: ( { state }: any ): UserInfo | Record<string, never> => {
return state.userinfo || {};
},
setUserinfo: ({ commit }: any, userinfo: UserInfo): void => {
commit({
type: 'SET_USERINFO',
payload: userinfo,
});
},
};
export default {
name: 'user',
reducer,
action
};
可以看出整个user由三部分组成state
、reducer
、action
同时对外暴露name
、reducer
、action
其中name为模块名,action是微应用唯一能直接访问的api, 而state只能由reducer改变
graph TD
action --> reducer --> state
- 将user模块导入,同时生成shared
// pool/index.ts
import Shared from 'micro-shared';
import User from './modules/user';
import Locale from './modules/locale';
const shared = new Shared({
modules: {
User,
Locale,
},
})
export default shared.getShared();
至此shared已编写完毕,接下来通过qiankun的props传给微应用即可。
- 在主应用项目中,进行qiankun的微应用注册的地方
import { registerMicroApps, start } from 'qiankun';
import shared from '@/pool';
registerMicroApps([
{
name: 'micro',
entry: '//localhost:8888',
container: '#nav',
activeRule: '/micro',
props: {
shared
},
},
]);
start();
- 在微应用中,接收shared实例
// @/main.ts 已隐藏无关代码
import SharedModule from '@/pool';
function render(props: any = {}) {
const { container, shared = SharedModule.getShared() } = props;
SharedModule.overloadShared(shared);
}
- 在微应用中创建 @/pool目录 (也是上一步里,
import SharedModule
的来源)
pool
├── index.ts
而@/pool/index.ts
也十分简单,相当于只需做模块注册即可
import SharedModule from 'micro-shared/sharedmodule';
import { Shared } from './shared';// 本地模块
SharedModule.initShared(Shared);// 加载本地模块
export default SharedModule;
第二行和第三行是用于加载本地shared实例(确保微应用独立运行时不会缺失shared),如果不考虑独立运行的话,这两行代码也可以删去。
- 现在你就可以在微应用自身的store里使用了
import Vue from 'vue';
import Vuex from 'vuex';
import SharedModule from '@/pool';// 从第6步创建的pool目录里引入
Vue.use(Vuex);
let shared:any = null;
export interface UserInfo {
username: string,
}
interface State {
locale: string,
userinfo: UserInfo | Record<string, never>,
}
export default new Vuex.Store({
state: {
locale: '',
userinfo: {},
},
mutations: {
SET_LOCALE: (state: State, locale: string) => {
state.locale = locale;
},
SET_USERINFO: (state: State, userinfo: UserInfo) => {
state.userinfo = userinfo;
},
},
actions: {
/*
初始化shared模块
建议在main.ts中,在执行完SharedModule.overloadShared(shared)后就执行该初始化
*/
initShared() {
shared = SharedModule.getShared();
this.dispatch('setLocale');
this.dispatch('setUserinfo');
SharedModule.subscribe([
(stateName: string) => {
if(stateName === 'locale') this.dispatch('setLocale');
},
(stateName: string) => {
if(stateName === 'user') this.dispatch('setUserinfo');
},
]);
},
setLocale({ commit }) {
const locale = shared.dispatch('locale/getLocale');
commit('SET_LOCALE', locale);
},
setUserinfo({ commit }) {
const userinfo = shared.dispatch('user/getUserinfo');
commit('SET_USERINFO', userinfo);
},
},
getters: {
locale: (state: State) => state.locale,
userinfo: (state: State) => state.userinfo,
},
modules: {
},
});
SharedModule.subscribe
用于注册订阅事件。通过传入回调函数进行订阅, 可以数组形式批量传入,当pool内数据有变化时(监听到redux提供的set方法执行了),会通过回调函数统一发布。- 注册的订阅事件可以接收一个参数 stateName,该参数会返回当前发生改变的state, 例如此次demo的state有 user 和 locale, 当user里的userinfo发生改变时, 每个订阅事件都会获得
stateName
参数,告诉你user
这个state发生了改变,这可以更好的帮助你决定更新哪些模块的状态 - 由于2实现的核心是
浅比较
,因此当stateName
为空字符串时,可以判断出是嵌套较深的state发生了改变,这在一定程度上也可以知道到底是哪个state改变了
api
SharedModule
api | 说明 |
---|---|
initShared | 加载本地shared |
overloadShared | 用于重载SharedModule内的shared实例 |
getShared | 获取SharedModule内部的shared实例 |
subscribe | 注册订阅事件(可传数组),在state发生改变后会触发此处订阅的事件 |
shared
api | 说明 |
---|---|
dispatch | 类似vuex的store.dispatch,用于调用不同模块的action |