微前端乾坤

news/2025/1/13 2:38:09/

1. 乾坤

简介
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统
官网:https://qiankun.umijs.org/zh/guide

2.使用

背景:
vue2.0 , vue-cli 5.0

主应用:

安装乾坤

 $ yarn add qiankun # 或者 npm i qiankun -S

main.js设置注册子应用

 import { registerMicroApps, start } from 'qiankun';registerMicroApps([{name: 'sub-vue',entry: '//172.16.20.177:8081',container: '#container',activeRule: '/app-vue/',props:{id:1}},]);start();

配置vue.config.js

const { defineConfig } = require('@vue/cli-service')
const { name } = require('./package');
module.exports = defineConfig({transpileDependencies: true,publicPath:'/',devServer: {headers: {'Access-Control-Allow-Origin': '*',},},configureWebpack: {output: {library: `${name}`,libraryTarget: 'umd'},},
})

app.vue中设置点击事件进行跳转
在这里插入图片描述

子应用:

vue2.0 , vue-cli5.0 ,webpack5.0
src下面设置一个public-path.js

if (window.__POWERED_BY_QIANKUN__) {// 这里不能擅自改为window不然微前端报错说找不到子应用入口/* global __webpack_public_path__:writable */ __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;}

vue.config.js

const { defineConfig } = require('@vue/cli-service')
const { name } = require('./package');
module.exports = defineConfig({transpileDependencies: true,publicPath: '/',devServer: {headers: {'Access-Control-Allow-Origin': '*',},},lintOnSave: false,configureWebpack: {output: {library: `vueApp`,libraryTarget: 'umd',globalObject: 'window'},},
})

main.js

import './public-path';
import Vue from 'vue'
import App from './App.vue'
import routes from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import VueRouter from 'vue-router';
Vue.config.productionTip = false
Vue.use(ElementUI);
let router = null;
let instance = null;console.log(window.__POWERED_BY_QIANKUN__, 'window.__POWERED_BY_QIANKUN__')
function render(props = {}) {const { container } = props;router = new VueRouter({// base: '/app-vue/',//.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',mode: 'hash',routes,});instance = new Vue({router,// store,render: (h) => h(App),}).$mount(container ? container.querySelector('#app') : '#app');
}// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {render();
}export async function bootstrap() {console.log('[vue] vue app bootstraped');
}
export async function mount(props) {console.log('[vue] props from main framework', props);render(props);
}
export async function unmount() {instance.$destroy();instance.$el.innerHTML = '';instance = null;router = null;
}

router/index.js
由于main.js 中new router了所以这里将原来的new router 改为输出路由数组
在这里插入图片描述

由于pushstate里面设置了前缀,所以路由子应用这里不设置前缀也可以直接访问

  {path: '/',name: 'home',component: HomeView},

问题:用pushstate后回到主应用未带前缀的页面子应用的前缀也会跟着一起,除非刷新页面第一次

实践中需要总结的问题

1.沙箱:

sandbox - boolean | { strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean } - 可选,是否开启沙箱,默认为 true。 experimentalStyleIsolation是在子应用的样式前面加上特定的一个hash属性,类似于scope但是不能防止全局在主应用的样式影响。
在这里插入图片描述

{ strictStyleIsolation: true } 时表示开启严格的样式隔离模式。这种模式下 qiankun 会为每个微应用的容器包裹上一个 shadow dom 节点,从而确保微应用的样式不会对全局造成影响。但是这个属性有兼容性,有时候需要特殊处理(react)。
在这里插入图片描述

看了官网对沙箱的叙述,总的来说有这个功能,但是效果不是很好,后续还在优化。看了很多文章也说乾坤沙箱能不用就不用。。。。

2.主子应用通信问题

1.主应用传递参数给子应用
RegistrableApp里面props方法,可以在子应用微前端生命周期钩子中都可以获取到该参数name

registerMicroApps([{name: 'app1',entry: '//localhost:8080',container: '#container',activeRule: '/react',props: {name: 'kuitos',},},],{beforeLoad: (app) => console.log('before load', app.name),beforeMount: [(app) => console.log('before mount', app.name)],},
);

2.loadMicroApp 手动加载微应用方法
该方法也有props参数可以传递数据给子应用

3.initGlobalState(state) 定义全局状态
在主应用中使用,在子应用中通过props获取数据

使用主应用和子应用都使用hash模式的时候

注意事项:

主应用中:注册子应用的时候activeRule需要加上 # (history模式的时候activeRule: /app-vue,不用加#)
在这里插入图片描述

方法一:能正常访问子应用的其他配置
路由需要特意加上相对应的前缀
hash模式的时候router中的base不用设置,publicPath变量也使用默认值

全局变量
window.POWERED_BY_QIANKUN 判断是否是微前端主应用进入
在这里插入图片描述
每当离开子应用,点击主应用页面的时候,会调用this.$destroy()方法销毁子应用内容
在这里插入图片描述

项目实战中遇到的问题:

1.Failed to fetch 一般是链接不上name 为sub-vue子应用
在这里插入图片描述
2.application ‘sub-vue’ died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in sub-vue entry。 这里一般是vue.config.js 中的publicPath参数有问题 看是不是默认的‘/’ 或者子应用的访问路径通过主应用访问不到
在这里插入图片描述
3.接入其他项目 png等图片404问题
原因:有可能项目没有引入public-path.js

在这里插入图片描述
解决方法:https://qiankun.umijs.org/zh/faq#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%BE%AE%E5%BA%94%E7%94%A8%E5%8A%A0%E8%BD%BD%E7%9A%84%E8%B5%84%E6%BA%90%E4%BC%9A-404

vue.config.js 添加即可解决

  chainWebpack: (config) => {config.module.rule('fonts').use('url-loader').loader('url-loader').options({}).end();config.module.rule('images').use('url-loader').loader('url-loader').options({}).end();},

在这里插入图片描述

4.样式隔离

乾坤会将主应用公共引入的css和其他vue中的样式转化为style 在主应用中head里面直接引入,就很容易造成子应用也同时使用该样式后被覆盖
在这里插入图片描述

在这里插入图片描述
这是在子应用设置了这个class,但是原则上子应用应该没有这个样式,不应该样式生效,但是由于主应用的原因颜色变成了蓝色,违背了两个项目互不干扰的原则。
在这里插入图片描述

在这里插入图片描述
解决方法:
主应用设置严格的沙箱模式
在这里插入图片描述
效果:
在这里插入图片描述


http://www.ppmy.cn/news/85101.html

相关文章

leetcode 29.两数相除

题目链接:leetcode 29 1.题目 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断,也就是截去(truncate)其小数部分。例如&#xff0c…

数字孪生智慧路灯可视化系统 区域控制节能增效

前言 智慧灯杆是智慧城市建设的重要组成部分,可以完成照明、公安、市政、气象、环保、通信等行业数据信息的采集、发布和传输。同时,作为5g时代车联网、云网、通信网络建设的重要组成部分,智慧灯杆也将得到广泛应用。 建设背景 城市路灯存…

前端小工具:批量修改图片信息

前端小工具一:批量修改文件夹里面的图片名称 步骤: 1.安装nodejs。 2.根据需要修改editFileName(filePath, formatName)函数的参数,也可以不改,直接将renameFile.js和img文件夹放在同一个目录下。 3.在renameFile.js目录下开启…

网安面试只要掌握这十点技巧,绝对轻轻松松吊打面试官

结合工作经验,在这里笔者给企业网管员提供一些保障企业网络安全的建议,帮助他们用以抵御网络入侵、恶意软件和垃圾邮件。 定义用户完成相关任务的恰当权限 拥有管理员权限的用户也就拥有执行破坏系统的活动能力,例如: ・偶然对系…

Android 14 又来了?别扶!抬起我来吧!

Android 14 又来了?别扶!抬起我来吧! 大家好,好久不见,从去年底写完年终总结之后就再也没有更新过文章,之前最多也就间隔一两个月时间,但这回间隔时间确实有点长,基本快半年了&…

阿里云手动创建Nginx-Ingress

阿里云相关文档 1、在ACK管理控制台点击如下 应用市场–>筛选(以ack-ingress-nginx-v1为例)–>点击安装–>一键部署–>自己定义集群、命名空间以及ingress名称 1.20以下集群选中ack-ingress-nginx。 1.20及以上集群选中ack-ingress-nginx-v1。 应用市场 筛选…

[Vue2] Vue2的12种组件通信

Vue2.x 组件通信共有12种 props$emit / v-on.syncv-modelref$children / $parent$attrs / $listenersprovide / injectEventBusVuex$rootslot 父子组件通信可以用 props $emit / v-on $attrs / $listeners ref .sync v-model $children / $parent 兄弟组件通信可以用 Even…

神马网络——IP地址

个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。座右铭:海不辞水,故能成其大;山不辞石,故能成其高。个人主页:小李会科技的…