乾坤微服务的使用

前言:

        在这里整理下用乾坤来开发微服务的一些资料。

使用好处:

        使用乾坤可以实现什么效果呢?众所周知,前端的框架五花八门,react/vue/angular等各领风骚,那么如果我们有需要把不同技术栈的项目整合起来,应该怎么去做呢?如果统一技术栈进行开发,工作量太大,成本也高,那还能怎么做呢?没错,这就是我们乾坤技术出来的由来,可以通过他把不同的项目进行一个融会贯通,让他们可以实现亲密的联系,又能各自发展。

乾坤的官网地址:点我

乾坤的逻辑流程:

如何去使用:

1、安装
yarn add qiankun
npm i qiankun -S 
2、主应用的main.js
// (1)导入乾坤框架
import { registerMicroApps, start } from "qiankun";
// (2)注册乾坤子应用
registerMicroApps([{name:"sub-application01", //子应用名称entry:"//localhost:8001", //子应用入库地址container:"#container", //主应用容器activeRule:"/sub-application01", //主应用路由匹配规则props:{token:"sub-application-001"} //主应用传递参数},// {//   name:"sub-application02",//   entry:"//localhost:8002",//   container:"#container",//   activeRule:"/sub-application02",//   props:{//     token:"sub-application-002"//   }// }
]);//(3)开启乾坤
start();
3、主应用的配置  initGlobalState(state)
  • 参数
  • state - Record<string, any> - 必选
  • 用法定义全局状态,并返回通信方法,建议在主应用使用,微应用通过 props 获取通信方法
import { initGlobalState } from 'qiankun';// 跨应用共享状态
const initialState = {hasCallPhone: false, // 是否拨打电话outsidePhone: '', // 外部电话号码isLocal: true, // 是否是本地号码channelId: '', // 渠道leadsId: '',hasSendMsg: false, // 是否发送短信maSend: {}, // MA的leadsId,channelIdhasSendEmail: false, // 是否发送邮件contactHistory: false, // 是否展示联系历史customerId: '', // 联系历史需要的id,newDict: false, // 是否新增字典addDictId: '', // 传入字典idcallDetails: false, // 是否展示通话详情channelSessionId: '', // 通话详情需要的idurgentObj: null, // 获取紧急程度socketCallback: null,taskList: [],isCustomerEdit: false, // 是否可以编辑客户trendsLayout: [], // 客户表单dynamicFields: [], // 动态字段fixedFieldsComponent: [], // 固定字段operateType: '', // 操作方式,是新增还是编辑callerName: '', // 主叫号人员名称calledName: '', // 被叫号人员名称roomNumber: '', // csp呼叫房间softPhone: {curOperate: '', // 呼叫状态hasSipConnected: false, // 电话连接状态mediaAvailabled: false, // 音频媒体webrtcConfig: {}, // 初始化连接webrtc配置},imPageNoticeInfo: {}, // 内部聊天页面通知相关数据iqcPageNoticeInfo: {}, // 内部支持页面通知相关数据reconnectCallback: null, // 内部支持断网重连回调reconnectImCallback: null, // IMcallVoiceCallback: null,callVoiceInfo: {},goConversation: false, // 通讯录跳转
};
const actions = initGlobalState(initialState);export default actions;
4、主应用中手动加载微应用的方式:
import { loadMicroApp } from 'qiankun';
let leftMicroApp = null;方法内部:
leftMicroApp = loadMicroApp({name: 'crm_core',entry: '//localhost:9011',container: '#wrapper__right',props: {path: 'customerTabs',},
});//组件销毁,调用子应用的 unmount方法
destroyed() {leftMicroApp.unmount()
},
5、子应用中
1、新建文件:public-path.ts/ public-path. js
/* eslint-disable camelcase */
if (window.__POWERED_BY_QIANKUN__) {__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
2、main.ts/main.js
import './core/public-path'// vue3中写法
const __qiankun__ = window.__POWERED_BY_QIANKUN__
__qiankun__ || render()// vue2中写法
//创建子应用渲染函数
function render(props = {}) {const { container } = props;router = new VueRouter({base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',mode: 'history',routes,});instance = new Vue({router,render: (h) => h(App),}).$mount(container ? container.querySelector('#app') : '#app');
};// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {render();
};
3、打包配置,vue.config.js
configureWebpack: {output: {library: `${name}-[name]`,libraryTarget: 'umd', // 把微应用打包成 umd 库格式jsonpFunction: `webpackJsonp_${name}`, filename: 'static/js/[hash:8].bundle.js'},},
6、微应用不需要额外安装任何其他依赖即可接入 qiankun 主应用。

微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。

生命周期钩子封装

/*** bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。*/
export async function bootstrap() {console.log('react app bootstraped');
}
/*** 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法*/
export async function mount(props) {}/*** 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例*/
export async function unmount(props) {}/*** 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效*/
export async function update(props) {console.log('update props', props);
}

个人项目中用法:

main.ts

import './core/public-path'
import { lifeCycle, render } from './core/life-cycle'const { bootstrap, mount, unmount } = lifeCycle()
export { bootstrap, mount, unmount }const __qiankun__ = window.__POWERED_BY_QIANKUN__
__qiankun__ || render()

life-cycle.ts

...
/*** 微应用生命周期*/
const lifeCycle = (): { [key: string]: (props?: qkProps) => Promise<void> } => {return {async bootstrap(props) {console.log(`bootstrap props: ${props}`);},async mount(props) {console.log(`mount props: ${props}`);if (props) {// 生成动态路由const availRoutes = assyAvailRoutes(props.menuLists, 1, "", APP_NAME);// 扁平化菜单树const flatMenus = flatMenuTree(props.menuLists);// 将菜单树、动态路由、扁平菜单树存入全局状态中store.commit("user/SET_MENUS", { menuLists: props.menuLists, availRoutes, flatMenus });// 将角色列表存入全局状态中store.commit("user/SET_ROLES", props.roles);store.commit("user/SET_USERINFO", props.userInfo);const routes = selfRoutes.concat(availRoutes);props.routes = routes;store.commit("chat/SET_SINGLE_CONFIG_EVO", []);// 如果开启内部聊天语音通话时获取有没有语音聊天权限if (matchFuncConfig("INTERNALCHAT_SOFTPHONE_ACTIVE") && store.state.chat.singleConfigEvo.length === 0) {getSingleMyConfigs();}// props.functions.sendOrder({//   message: {//     type: 'typing',//     sendUserId: '',//     groupType: ''//   }// });actions.setActions(props);actions.setGlobalState({socketCallback: (data: any, extraParams: any) => {store.commit("chat/SET_SOCKET_MAINAPP_PARAMS", extraParams);const { namespace } = extraParams;// 接收到父应用分发的消息,进行处理if (namespace === "im") {if (data.type === spm.ON_PING) {imDispatchMessage({ messageType: cmd.SOCKET_PING });} else {imDispatchMessage({messageType: enumMsg[data.messageType],message: data.message,});}}if (namespace === "iqc") {if (data.type === spm.ON_PING) {iqcDispatchMessage({ messageType: cmd.SOCKET_PING });} else {iqcDispatchMessage({messageType: enumMsg[data.messageType],message: data.message,});}}},// 断网重连回调reconnectCallback: () => {store.commit("internal/SET_RECONNECTED_COUNT");},// 断网重连回调reconnectImCallback: (networkStatus:string) => {utilHelper.handleDisconnectOrOnreconnected(networkStatus)console.log('##################执行reconnectImCallback',networkStatus);},});}await render(props);},async unmount() {// 关闭所有的页面通知实例const { pageNoticeInstances = {} } = store.state.chat;const instanceKeys = Object.keys(pageNoticeInstances);forEach(instanceKeys, (key) => {const notifyInstance = pageNoticeInstances[key];notifyInstance.close();});console.log("unmount props");instance.unmount();instance = null;router = null;},async update(props) {console.log(`update props: ${props}`);},};
};async function render(props?: qkProps): Promise<void> {let basePath = "";// 如果是生产环境if (process.env.NODE_DEV === "production") {// 如果是子应用,使用二级域名前缀,反之使用带internalPortal三级域名basePath = __qiankun__ ? `/${APP_NAME}` : `/internalPortal/${APP_KEY}/`;} else {// 如果非生产环境,并且不是子应用,basePath = __qiankun__ ? `/${APP_NAME}` : "/";}// 初始化固定路由let routes = selfRoutes;if (__qiankun__) {// 如果是微应用,则使用主应用传递的路由集合if (props?.routes) routes = props?.routes;} else if (store.state.user.accessToken) {// 如果没有授权令牌// 请求菜单树,非子应用时不控制权限const response: AxiosResponse = await axiosSingle(getCompleteTree(), false);if (response.data.length > 0) {// 获取当前子应用相关的菜单let menuLists = response.data[0].children.filter((item: IMenu) =>includes(["conversation", "organization"], item.i18n));// 递归生成菜单menuLists = recurseTree(menuLists, "");if (menuLists.length) {// 生成动态路由const availRoutes = assyAvailRoutes(menuLists, 1, "", APP_NAME);// 扁平化菜单树const flatMenus = flatMenuTree(menuLists);// 将菜单树、动态路由、扁平菜单树存入全局状态中store.commit("user/SET_MENUS", { menuLists, availRoutes, flatMenus });// 叠加固定路由和动态路由// routes = selfRoutes.concat(availRoutes)selfRoutes[0].children = availRoutes;routes = selfRoutes;}}}router = createRouter({history: createMemoryHistory(basePath),routes,});instance = createApp(App).use(router).use(store).use(i18n).use(plugin, { imports: [] });// 全局注册El组件components.forEach((item) => {if (item) instance.use(item);});// 全量导入El图标for (const key in Icons) {if (Reflect.has(Icons, key)) {instance.component(key, Icons[key]);}}// 注册按钮授权指令instance.use(authDirective);// 注册按钮授权全局方法instance.config.globalProperties.$vAuth = function (key: any) {return directiveAuth(this, key);};instance.use(draggable);instance.mount(props?.container ? props.container.querySelector("#appInternalChat") : "#appInternalChat");// instance.use(VueVirtualScroller);// instance.component('DynamicScroller', VueVirtualScroller.DynamicScroller)// 前置路由守卫router.beforeEach(async (to: any, from: any) => {if (!__qiankun__) {// 1 如果不是子应用if (store.state.user.accessToken) {if (!store.state.user.userInfo) {const infoConfig = configRequest(`${GlobalConfig.API_HRMS_URL}/employee/current`, httpMethod.GET);const response1 = await axiosSingle(infoConfig);const userInfo = response1.data;store.commit("user/SET_USERINFO", userInfo);// 1.1 如果有授权令牌if (to.path === "/login") {// 1.1.1 如果访问页面为登录页,则跳转到首页return "/";} else if (to.matched.length) {// 1.1.2 如果有匹配的路由,则进行跳转return true;} else {// 1.1.3 如果找不到匹配路由,则跳转到未授权报错页面// next({ path: '/403', replace: true })return false;}}} else if (to.path === "/login" && to.query.code) {// 1.2 如果没有令牌并跳转到登录页,并有授权码return true;} else {// 如果没有令牌并且没有授权码,则跳转到sso进行登录signIn();}} else if (to.matched.length) {// 2 如果是子应用,并且有匹配的路由,则进行跳转return true;} else {// 3 如果没有匹配路由,则跳转到未授权报错页面// next({ path: '/403', replace: true })return false;}});
}export { lifeCycle, render };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql启动报错:本地计算机上的mysql服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止

某天开机,发现Mysql被异常关闭,并且启动不起来,出这篇文章也是为了下次遇到类似问题,迅速解决(请细读文章,因为第二个方案才是主要方案) 第一个解决方案 我采用的第一个方法查“端口占用“问题(因为这是一篇博客所以我写的操作比较详细为了方便后面看这篇博客的人,我自…

如何在前端项目中用字体图标替换图片,方便减小打包体积和统一切换颜色

1.进入阿里妈妈矢量图标图库 地址&#xff1a;阿里妈妈矢量图 2.搜索自己想要的图标 3.添加自己想要的图标 4.把刚才选的图标&#xff0c;添加到自己要下载的项目 5.把项目下载到本地 6.引入iconfont.css 在div上增加对应的类名就可以啦 下载的所有类名都在下面的demo_index…

MySQL从5.7升级到8.0步骤及其问题

MySQL从5.7升级到8.0步骤及其问题 前言 本文源自微博客&#xff0c;且以获得授权&#xff0c;请尊重版权。 一、需求背景 Docker环境下&#xff0c;MySQL5.7升级到8.0&#xff0c;数据迁移时使用的是mysqldump方式迁移。 二、迁移步骤 数据备份&#xff1a; docker exec -i 1…

python-画三角形

[题目描述] 输入一个正整数n&#xff0c;请使用大写字母拼成一个这样的三角形图案&#xff08;参考样例输入输出&#xff09;&#xff1a;三角形图案的第1行有1个字母&#xff0c;第2行有2个字母&#xff0c;以此类推&#xff1b;在三角形图案中&#xff0c;由上至下、由左至右…

使用高德API计算两个地址的距离

要使用高德地图API来计算两个城市之间的距离&#xff0c;你需要首先在高德开放平台上注册并获取API密钥&#xff08;AK&#xff09;。以下是一个使用Java调用高德地图API来计算两个城市之间距离的示例代码。 步骤 1: 获取高德地图API密钥 访问高德开放平台&#xff08;https:…

GIS设计与开发课程设计(三)

环境&#xff1a;Windows10专业版 ArcGIS10.2 ArcEngine10.2 Visual Studio 2019 因每个人电脑版本和软件版本不同&#xff0c;运行的结果可能不同 系列文章&#xff1a; GIS设计与开发课程设计&#xff08;一&#xff09; GIS设计与开发课程设计&#xff08;二&#xff09;…

Apple Watch开发入门知识,还是很有必要的

随着现在 Apple 生态圈的发展&#xff0c;越来越多的 App 会把自己的简化版从 iOS 迁移至 WatchOS&#xff08;支付宝、微信、手Q、头条、QQ音乐、网易云音乐等等&#xff0c;都有Watch版App&#xff09;。官方开发文档&#xff1a;Setting up a watchOS project | Apple Devel…

神经网络学习3-卷积层

膨胀卷积&#xff0c;也被称为空洞卷积或扩张卷积&#xff0c;是一种特殊的卷积运算&#xff0c;它在标准卷积的基础上引入了一个额外的超参数&#xff0c;即膨胀率&#xff08;dilation rate&#xff09;。这个超参数决定了在卷积核的元素之间插入多少额外的空间。通过这种方式…

04-对原生app应用中的元素进行定位

本文介绍对于安卓原生app应用中的元素如何进行定位。 一、uiautomatorviewer uiautomatorviewer是Android-SDK自带的一个元素定位工具&#xff0c;非常简单好用&#xff0c;可以使用该工具查看app应用中的元素属性&#xff0c;帮助我们在代码中进行元素定位。 1&#xff09;使…

el-table 固定前n行 配合 max-height 生效

:row-class-name"TableRowClassName" 加上类名 <el-table:data"computedTableList"borderstyle"width: 100%":row-class-name"TableRowClassName"max-height"800"><el-table-column fixed prop"name"…

【OS基础】符合AUTOSAR标准的RTAOS-Alarms详解

目录 前言 正文 7.报警Alarms 7.1配置Alarms 7.1.1激活一个任务 7.1.2 设置一个事件 7.1.3报警回调Alarm Callback 7.1.4 增加计数器值 7.2设置Alarms 7.2.1 绝对Alarms 7.2.2 相对Alarm 7.3自启动Alarms 7.4 删除Alarms 7.5确认何时会发生Alarm 7.6非周期Alarm…

细致解析跨境电商多平台搭建利器-179海关接口源码应用方法

介绍 跨境电商已成为当前电商行业的热门发展方向之一。为满足跨境电商的需求&#xff0c;各大平台纷纷推出了多平台搭建利器。其中&#xff0c;179海关接口源码是一款非常实用的工具&#xff0c;本文将对其应用方法进行细致解析。 了解179海关接口源码 179海关接口源码可以帮…

2024最新版Vcpkg安装第三方库报错error: building XXXX failed with: BUILD_FAILED

很多朋友用Vcpkg安装第三方库的时候基本都会遇到报错的情况&#xff0c;而且大部分都会出现下面这个页面里面的红色报错信息&#xff0c;但是实际上真正错误应该是上面的Cmake Error提示&#xff0c;下面的红色警告只是Vcpkg官方提供给我们的一个最基础的解决方式&#xff0c;而…

【Docker系列】深入解析 Docker 容器部署脚本

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【稳定检索/投稿优惠】2024年生物技术与食品科学国际会议(ICBFS 2024)

2024 International Conference on Biotechnology and Food Science 2024年生物技术与食品科学国际会议 【会议信息】 会议简称&#xff1a;ICBFS 2024 大会时间&#xff1a;点击查看 截稿时间&#xff1a;点击查看 大会地点&#xff1a;中国厦门 会议官网&#xff1a;www.icb…

汇聚荣优势是什么?

汇聚荣优势是什么?在探讨企业成功之道时&#xff0c;我们不得不提及“汇聚荣优势”这一概念。简而言之&#xff0c;它指的是企业通过整合内外部资源&#xff0c;形成独特的竞争优势&#xff0c;以实现持续发展与市场领先地位的战略行为。这种优势的构建不是一蹴而就的&#xf…

生信网络学院|06月21日《SolidWorks Costing助力制造企业建立成本核算体系》

课程主题&#xff1a;SolidWorks Costing助力制造企业建立成本核算体系 课程时间&#xff1a;2024年06月21日 14:00-14:30 主讲人&#xff1a;张丹清 生信科技 售前顾问 Costing成本分析简介钣金件成本分析加工件成本分析装配体成本分析总结&答疑 安装腾讯会议客户端或…

Windows上使用vscode配置C/C++编译环境

GCC和GDB 一句话概括&#xff1a;gcc用来编译C&#xff0c;gdb用来调试C。 GCC (GNU Compiler Collection) GCC&#xff08;GNU编译器套件&#xff09;是一个由GNU项目开发的编译器系统&#xff0c;支持多种编程语言&#xff0c;如C、C、Objective-C、Fortran、Ada和Go等。G…

ARM32开发-fat_fs文件系统

FAT_FS 文件系统 FAT (File Allocation Table) 文件系统是一种广泛使用的基于磁盘的文件系统,尤其适用于小型嵌入式系统和存储卡。FAT_FS 就是一个专门针对 FAT 文件系统的开源实现。 FAT_FS 的主要特点 轻量级和高度可移植: FAT_FS 是一个非常轻量级的文件系统实现,占用资源少…

人脸识别考勤机给企业带来了哪些好处

人脸识别考勤机给企业带来了哪些好处 随着考勤软件在国内各企业中逐渐使用&#xff0c;人们对于考勤的这种方式已不再生疏&#xff0c;传统的纸质签到、指纹打卡已因存在不灵敏、易作弊、难统计等诸多弊病&#xff0c;逐步被可以管理考勤的手机软件索取代&#xff1b; 近些…