微前端 qiankun 框架接入问题记录

背景:需要搭建一个平台,这个平台的主要功能是集成各个子系统,方面对系统之间的统一管理。在搭建这样一个平台时,前端考虑使用微前端架构方式实现,使用的框架是 qiankun,本文主要记录在 qiankun 框架使用过程中遇到的问题,及解决方法。

问题一:本地联调时报跨域问题及子应用无法 fetch 到,如下:

解决方法,修改主应用的配置,如下:

问题二:主应用可以连接到子应用,但在主应用中未显示子应用,如下:

解决方法,修改主应用的配置,如下:

主应用中未提供子应用需要挂载的 dom 元素

问题三:vue-router3 路由重复点击页面报错,如图:

解决方法,在 router 路由文件中修改 push replace 方法:

import Vue from 'vue';
import VueRouter from 'vue-router';
import HomeView from '../views/HomeView.vue';
import AboutView from '../views/AboutView.vue';
import MicroApp from '../components/MicroApp.vue';Vue.use(VueRouter);const { isNavigationFailure, NavigationFailureType } = VueRouter;
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {return originalPush.call(this, location).catch((failure) => {if (isNavigationFailure(failure, NavigationFailureType.aborted)) {throw failure;}});
};const originalReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function replace(location) {return originalReplace.call(this, location).catch((failure) => {if (isNavigationFailure(failure, NavigationFailureType.aborted)) {throw failure;}});
};const routes = [{path: '/',name: 'home',component: HomeView,},{path: '/about',name: 'about',component: AboutView,},{path: '/child-app1',component: MicroApp,},
];const router = new VueRouter({mode: 'history',routes,
});export default router;

问题四:主应用加载子应用之后,子应用内的路由跳转失败,如图:

解决方法,在路由文件中修改加载子应用的路由,并在修改主应用中的路由跳转方法,如图:

参考链接:导航故障 | Vue Router

qiankun 接入时的前期问题,大多是配置错误,主应用和子应用 name 对应不上,或者主应用未给子应用提供容器标签等,主要参考链接:

常见问题 - qiankun

简单总结:

1、主应用配置

主应用挂载组件:/component/Micro.vue

安装 qiankun

$ yarn add qiankun # 或者 npm i qiankun -S
document.subApps = [{name: 'childApp1',entry: '//localhost:8081/child-app1/',container: '#container-child-app1',activeRule: '/child-app1',},
];
<template><div id="container-child-app1"></div>
</template><script>
import { loadMicroApp } from 'qiankun';
import actions from '../../actions.js';export default {name: 'microApp',mixins: [actions],data() {return {microApp: null,};},mounted() {const getMicroInfo = this.getMicroInfo();this.microApp = loadMicroApp(getMicroInfo, { singular: true });},beforeDestroy() {this.microApp.unmount();},methods: {// 手动加载微应用getMicroInfo() {const appIdentifying = this.$route.path.split('/')[1];let data = {};const href = window.location.host;for (let i = 0; i < document.subApps.length; i++) {const element = document.subApps[i];if (element.activeRule.includes(appIdentifying)) {if (typeof element.entry !== 'string') {data = {...element,entry: element.entry[href]? element.entry[href]: Object.values(element.entry)[0],};} else {data = { ...element };}data.props = {token: {userInfo: {userName: '小明',userId: '123',date: new Date().toLocaleString(),},},};data.activeRule = [appIdentifying];break;}}console.log('data::', data);return data;},},
};
</script>

 组应用挂载子应用的路由修改:

import Vue from 'vue';
import VueRouter from 'vue-router';
import HomeView from '../views/HomeView.vue';
import AboutView from '../views/AboutView.vue';
import MicroApp from '../components/MicroApp.vue';Vue.use(VueRouter);const { isNavigationFailure, NavigationFailureType } = VueRouter;
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {return originalPush.call(this, location).catch((failure) => {if (isNavigationFailure(failure, NavigationFailureType.aborted)) {throw failure;}});
};const originalReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function replace(location) {return originalReplace.call(this, location).catch((failure) => {if (isNavigationFailure(failure, NavigationFailureType.aborted)) {throw failure;}});
};const routes = [{path: '/',name: 'home',component: HomeView,},{path: '/about',name: 'about',component: AboutView,},{// 子应用路由path: '/child-app1',component: MicroApp,},
];const router = new VueRouter({mode: 'history',routes,
});export default router;

App.vue 可以指定子应用容器位置:

<template><div id="app"><container-main><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item><el-button type="text" @click="handleJumpParentHome">主应用 home</el-button></el-breadcrumb-item><el-breadcrumb-item><el-button type="text" @click="handleJumpParentAbout">主应用 about</el-button></el-breadcrumb-item><el-breadcrumb-item><el-button type="text" @click="handleJumpChildApp1">子应用 home</el-button></el-breadcrumb-item></el-breadcrumb><!-- 可以不写,写了之后未指定了子应用挂载位置 --><div id="container-child-app1"></div></container-main><router-view /></div>
</template><script>
import ContainerMain from './components/ContainerMain.vue';export default {name: 'App',components: {ContainerMain,},data() {return {};},methods: {handleJumpParentHome() {this.$router.push({path: '/',});},handleJumpParentAbout() {this.$router.push({path: '/about',});},handleJumpChildApp1() {this.$router.push({path: '/child-app1',});},},
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}
</style>

2、子应用配置

main.js 中配置:

import Vue from 'vue';
import App from './App.vue';
import routes from './router';
import VueRouter from 'vue-router';
import store from './store';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';Vue.config.productionTip = false;
Vue.use(ElementUI);if (window.__POWERED_BY_QIANKUN__) {/* eslint-disable @typescript-eslint/camelcase */__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}let router = null;
let instance = null;
function render(props = {}) {console.log('子应用 render props::', props, 'instance====', instance);// sessionStorage.setItem('userInfo', JSON.stringify(props.token.userInfo));const { container } = props;router = new VueRouter({base: window.__POWERED_BY_QIANKUN__ ? '/child-app1/' : '/',mode: 'history',routes});instance = new Vue({router,store,render: (h) => h(App)}).$mount(container ? container.querySelector('#app') : '#app');
}// 独立运行时
/* eslint-disable */
if (!window.__POWERED_BY_QIANKUN__) {render();
}export async function bootstrap() {console.log('子应用 bootstrap ===========================');
}let initialState = null;
export async function mount(props) {console.log('子应用 mount props ===============', props);sessionStorage.setItem('userInfo', JSON.stringify(props.token.userInfo));props.onGlobalStateChange((state, prev) => {// state: 变更后的状态; prev 变更前的状态console.log('子应用获取共享数据 state::', state, 'prev::', prev);// 接收主应用中的共享数据 并将其设置为全局变量Vue.prototype.$initialState = state;});props.setGlobalState({initialState:'子应用中修改主应用中的全局变量,实现住应用子应用间数据的双向双向通信'});render(props);
}
export async function unmount() {console.log('子应用 unmount==========');instance.$destroy();instance.$el.innerHTML = '';instance = null;router = null;
}

子应用中的打包配置修改:

const { defineConfig } = require('@vue/cli-service');module.exports = defineConfig({transpileDependencies: true,publicPath: '/child-app1/',devServer: {headers: {'Access-Control-Allow-Origin': '*'}},configureWebpack: {output: {/**{name: 'childApp1',entry: '//localhost:8081/child-app1/',container: '#container-child-app1',activeRule: '/child-app1',},library 与 主应用中的 name 保持一致**/library: `childApp1`,libraryTarget: 'umd', // 把微应用打包成 umd 库格式chunkLoadingGlobal: `webpackJsonp_childApp1` // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal}}
});

代码上传到了 github 上,后序会持续更新代码。

GitHub - 13523010484/qiankun-vue

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

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

相关文章

第20天:信息打点-红蓝队自动化项目资产侦察企查产权武器库部署网络空间

第二十天 一、工具项目-红蓝队&自动化部署 自动化-武器库部署-F8x 项目地址&#xff1a;https://github.com/ffffffff0x/f8x 介绍&#xff1a;一款红/蓝队环境自动化部署工具,支持多种场景,渗透,开发,代理环境,服务可选项等.下载&#xff1a;wget -O f8x https://f8x.io…

【MATLAB源码-第31期】基于matlab的光通信中不同调制方式的误码率对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 光通信&#xff1a; 光通信是一种利用光波传输信息的技术。它使用光信号作为信息的载体&#xff0c;通过调制光波的特性来传输数据&#xff0c;通常利用光纤作为传输介质。光通信具有高带宽、低延迟和大容量等优点&#…

利用CNN-Bigru-Attention模型输电线路故障诊断(Python代码,TensorFlow框架,)

效果视频&#xff1a;利用CNN-Bigru-Attention模型输电线路故障诊断(Python代码&#xff0c;TensorFlow框架&#xff0c;压缩包带有数据集和代码&#xff0c;解压缩可直接运行)_哔哩哔哩_bilibili 售后包免费远程协助运行&#xff08;用向日葵或者todesk软件协助&#xff09; …

构建数据平台架构指导原则与平台核心组件说明

文章目录 前言什么是数据架构&#xff1f;数据架构如何帮助构建数据平台&#xff1f;数据平台核心组件数据源系统数据加载数据存储数据处理和转换提供使用数据的方式公共服务 前言 湖仓一体是最近几年非常流行的现代大数据架构&#xff0c;目前它已经成为设计数据平台架构的首…

权威Scrum敏捷开发企业级实训/敏捷开发培训课程

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏…

【yolo数据集合并方法】

yolo数据集合并方法 1.数据集容2.数据集合并 1.数据集容 包含训练集、验证集和测试集。 每一个数据集中包含图像文件夹和标签文件夹。 yaml文件中定义了配置参数&#xff0c;包括目标识别的class类别&#xff1a; 2.数据集合并 需要修改labels文件夹下txt文件class信息&…

用html画一个睡觉的熊动画

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>睡觉的熊动画</title><link rel"stylesheet" href"./style.css"> </head><body><div id"contain…

reportlab 生成pdf文件 (python)

1 安装 pip install reportlab2 应用场景 通过网页动态生成PDF文档大量的报告和数据发布用XML一步生成PDF 官网案例 3 PLATYPUS Platypus是“Page Layout and Typography Using Scripts”&#xff0c;是使用脚本的页面布局和印刷术的缩写&#xff0c;这是一个高层次页面布局…

Python-Qt上位机设计

1.下载designer软件 2.自己设计一个界面 3.在指定部件加入点击响应命令函数名 鼠标点击目标部件拖出信号线 4.保存生成.ui文件&#xff0c;用pycharm打开 5.生成.py文件 6.新建一个功能文件 上图中class MainWindow的具体代码不予展示。 7.生成exe文件 将写好的py文件保存&a…

CentOS 7 下安装RabbitMQ教程(亲测有效)

一、做准备&#xff08;VMWare 虚拟机上的 CentOS 7 镜像 上安装的&#xff09; &#xff08;1&#xff09;准备RabbitMQ的安装包&#xff08;rabbitmq-server-3.9.0-1.el7.noarch.rpm&#xff09;下载地址mq &#xff08;2&#xff09;还得准备erlang语言&#xff08;erlang…

AcWing 796. 子矩阵的和——算法基础课题解

AcWing 796. 子矩阵的和 题目描述 输入一个 n 行 m 列的整数矩阵&#xff0c;再输入 q 个询问&#xff0c;每个询问包含四个整数 x1,y1,x2,y2&#xff0c;表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 n&…

MT2046 巨大的错误

1.暴力代码 2/10 #include <bits/stdc.h> using namespace std; int n; int a[25]; int b[25]; int ans 0; bool err() {for (int i 1; i < n; i){if (a[i] b[i]){return false;}}return true; } int main() {cin >> n;for (int i 1; i < n; i){a[i] i…