重庆网站建设哪里好,秦皇岛解封最新消息今天,建设网站需要的人才,中牟做网站因公司需求 需要将原本vue2iframe 形式的项目改成微前端乾坤的方式。
之前iframe都是直接嵌套到vue2项目的二级目录或者三级目录下的(反正就是要随处可嵌)
用乾坤的原因#xff1a; 1、iframe嵌套的方式存在安全隐患#xff1b; 2、项目是联合开发的#xff0c; 乾坤的方便…因公司需求 需要将原本vue2iframe 形式的项目改成微前端乾坤的方式。
之前iframe都是直接嵌套到vue2项目的二级目录或者三级目录下的(反正就是要随处可嵌)
用乾坤的原因 1、iframe嵌套的方式存在安全隐患 2、项目是联合开发的 乾坤的方便多团队开发 3、乾坤方便后续增加子应用继续开发
注意使用场景原本vue2iframe 形式的项目改成微前端乾坤的方式将vue2改成微服务的主应用基座之前iframe嵌套在vue2项目中的其他页面的系统改成微服务的子应用嵌套的只是子应用路由中的一个页面 也就是 主应用 的一个 路由页面 对应 子应用 的一个 路由页面 不是那种常规的一个出口包含了整个子应用一下主应用的配置主要是针对我这种需求弄的 子应用大部分都是通用的 一、乾坤介绍
1、简介
简单无论你使用什么技术栈都可以轻松地将子应用接入到主应用中就像使用 iframe 一样简单。完备qiankun 提供了丰富的功能包括样式隔离、沙箱、预加载等为开发者解决微前端架构中的各种问题。生产可用qiankun 已经在蚂蚁金服内部和外部的 200 应用中得到验证是一个值得信赖的生产可用解决方案。
2、qiankun 的设计理念
qiankun 的设计理念主要体现在两个方面技术栈无关和技术栈无关。技术栈无关qiankun 不限制子应用的技术栈无论是 React、Vue 还是 Angular都可以轻松地接入到主应用中。这样可以消除应用之间的隐性依赖实现真正的技术栈无关。接入简单qiankun 的目标是让接入微前端的过程就像使用 iframe 一样简单从而尽可能减少对旧应用的改造工作量。
3、qiankun 的技术实现与选择
qiankun 在技术实现上主要解决了两个问题应用的加载与切换和应用的隔离与通信。应用的加载与切换qiankun 通过使用 single-spa实现了应用的懒加载、路由处理和应用入口选择等功能。应用的隔离与通信qiankun 使用 JS 沙箱和样式隔离技术确保子应用之间的 JS 和 CSS 不会发生冲突。同时qiankun 提供了父子应用和子子应用之间的通信机制实现了应用之间的数据传递和交互。 二、项目改造
我的项目目录格式 1、主应用base 1、安装乾坤
yarn add qiankun -S / npm i qiankun -S 2、在需要嵌套子应用页面的页面主应用指定菜单下之前iframe页面的地方添加如下内容在文件中准备子应用出口容器 然后script中引入loadMicroApp方法加载子应用
!--* Description: ------------ fileDescription -----------* Author: snows_l snows_l163.com* Date: 2023-09-13 18:02:20* LastEditors: snows_l snows_l163.com* LastEditTime: 2024-02-27 12:19:54* FilePath: /digital-qiankun-common/base/src/views/machineRoom/index.vue
--templatediv idmicroAppContainer/div
/templatescript
import { loadMicroApp } from qiankun;export default {data() {return {microApp: null,};},mounted() {this.microApp loadMicroApp({name: cmdb,entry: //localhost:8991/, // 子应用部署的服务地址、这里因为都是本地开所以是localhost,到时候部署到那个服务器就是那个服务器地址container: #microAppContainer,// props 传参props: {token: sessionStorage.getItem(token),localLogin: sessionStorage.getItem(local_login),roleNamesStr: sessionStorage.getItem(roleNamesStr),},},{// 是否开启沙箱样式隔离sandbox: {// experimentalStyleIsolation: false, // 沙箱隔离// strictStyleIsolation: false, // 样式隔离处于实验阶段 是导致主应用的样子错乱 用的话请检查主应用的样式是否被影响},// 是否为单实例场景单实例指的是同一时间只会渲染一个微应用。默认为 false。singular: true,});},updated() {if (this.microApp) {this.microApp.update();}},beforeDestroy() {if (this.microApp) {this.microApp.unmount();}},
};
/script 3、路由由于是主应用与子应用的页面是多对多 主应用需要包含菜单头部logo、头像等title组件 所以需要包含在layout组件内 因此主应用与子应用的路由需要一样相当于主应用与子应用使用同一个路由路由的component都指定同一个vue文件因为只有子应用的出口就只有这个一个文件。如下
// 主应用
{path: /operations/machineRoom,redirect: { name: MachineRoom },component: Layout,meta: { title: 多云现场设备管理, icon: 资源展示 },children: [{path: machineRoom,name: MachineRoom,component: () import(/views/machineRoom/index), // 同一个页面},{path: hardware,name: Hardware,component: () import(/views/machineRoom/index), // 同一个页面},],
},// 子应用路由
{name: resource,path: /operations/machineRoom/:code,component: () import(/pages/resource/index)
}
这样主应用就搭建好了 给子应用留了出口 2、vue2子应用 我这里子应用用的histor模式的路由 子应用用的都是 1、在src目录下添加public-path.js文件 并在main.js入口文件中引入 public-path.js的内容如下 if (window.__POWERED_BY_QIANKUN__) {__webpack_public_path__ window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}2、改造mian.j入口文件如下 在入口文件中添加乾坤子应用的渲染方式 并导出乾坤使用的三个生命周期钩子函数改造成如下----- 根据自己应用参考配置
import Vue from vue;
import VueRouter from vue-router;
import App from ./App.vue;
import ./public-path;
import routes from ./router;Vue.config.productionTip false;let router null;
let instance null;function render(props {}) {const { container } props;router new VueRouter({base: window.__POWERED_BY_QIANKUN__ ? /#/ : /, // 如果在乾坤环境 由于主应用是hash模式的路由所以需要加/#/ 独立运行子应用是history, 所以是/mode: history,routes});instance new Vue({router,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;
} 3、路由主应用的路由于微应用的路由保持一直主应用中已经提到 4、在webpack.config.js 或者 vue.config.js中添加如下内容
const { name } require(./package);
devServer: {port: 8031,headers: {Access-Control-Allow-Origin: *, },
},configureWebpack: {output: {library: ${name}-[name],libraryTarget: umd, // 把微应用打包成 umd 库格式// webpack5 使用chunkLoadingGlobal: webpackJsonp_${packageName},jsonpFunction: webpackJsonp_${packageName},},
}, 5、打包需要打包成umd库格式配置如下 webpack5打包 添加如下内容
const packageName require(./package.json).name;
module.exports {output: {library: ${packageName}-[name],libraryTarget: umd,chunkLoadingGlobal: webpackJsonp_${packageName},},
}; webpack4打包 添加如下内容
const packageName require(./package.json).name;module.exports {output: {library: ${packageName}-[name],libraryTarget: umd,jsonpFunction: webpackJsonp_${packageName},},
}; 3、vue3子应用webpack打包 1)、在入口文件中添加乾坤子应用的渲染方式 并导出乾坤使用的三个生命周期钩子函数改造成如下----- 根据自己应用参考配置
/** Description: ------------ fileDescription -----------* Author: snows_l snows_l163.com* Date: 2023-09-26 09:05:04* LastEditors: snows_l snows_l163.com* LastEditTime: 2024-03-01 16:04:40* FilePath: /digital-qiankun-common/cmdb_vue/src/main.js*/
import Antd from ant-design-vue;
import ant-design-vue/dist/reset.css;
import { createApp } from vue;
import { createRouter, createWebHistory } from vue-router;
import App from ./App.vue;
import ./public-path;
import routers from ./routers/index.js;
import myPinia from ./store;let app null;
let router null;const render container {app createApp(App);// 如果是在主应用的环境下就挂载主应用的节点否则挂载到本地router createRouter({history: createWebHistory(window.__POWERED_BY_QIANKUN__ ? /#/ : /),routes: routers});const appDom container ? container.querySelector(#app) : #app;app.use(router);app.use(Antd);app.use(myPinia);app.mount(appDom);
};// 独立运行
if (!window.__POWERED_BY_QIANKUN__) {render(null);
}export async function bootstrap() {console.log([vue] vue app bootstraped);
}export async function mount(props) {render(props.container);
}export async function unmount() {app.unmount();app null;router null;
} 2)、在main.js同级目录添加public-path.js文件 并在main.js中引入
if (window.__POWERED_BY_QIANKUN__) {__webpack_public_path__ window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}3)、在vue.config.js的server添加如下内容
headers: {Access-Control-Allow-Origin: * // 主应用获取子应用时跨域响应头
}4)、固定端口主应用中会用到(开发环境用发布的时候用的子应用部署的服务器地址) 4、vue3子应用vite 1、安装vite的乾坤插件
yarn add vite-plugin-qiankun -D / npm i vite-plugin-qiankun -D 2、在入口文件中添加乾坤子应用的渲染方式 并导出乾坤使用的三个生命周期钩子函数改造成如下----- 根据自己应用参考配置
/** Description: ------------ fileDescription -----------* Author: snows_l snows_l163.com* Date: 2023-09-26 09:05:04* LastEditors: snows_l snows_l163.com* LastEditTime: 2024-02-27 10:36:31* FilePath: /digital-qiankun-common/CMDB/src/main.js*/import { qiankunWindow, renderWithQiankun } from vite-plugin-qiankun/dist/helper;
import { createApp } from vue;
import { createRouter, createWebHistory } from vue-router;
import App from ./App.vue;
import routers from ./routers/index.js;import Antd from ant-design-vue;
import ant-design-vue/dist/reset.css;
import ElementPlus from element-plus;
import element-plus/dist/index.css;
import zhCn from element-plus/dist/locale/zh-cn.mjs;
import myPinia from ./store;let app null;
let router null;const render container {app createApp(App);// 如果是在主应用的环境下就挂载主应用的节点否则挂载到本地router createRouter({history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? /#/ : /),routes: routers // routes: routes 的缩写});const appDom container ? container.querySelector(#app) : #app;app.use(router);app.use(Antd);app.use(ElementPlus, {locale: zhCn});app.use(myPinia);app.mount(appDom);
};if (!qiankunWindow.__POWERED_BY_QIANKUN__) {render(null);
} else {renderWithQiankun({// bootstrap 只会在微应用初始化的时候调用一次下次微应用重新进入时会直接调用 mount 钩子不会再重复触发 bootstrap// 通常我们可以在这里做一些全局变量的初始化比如不会在 unmount 阶段被销毁的应用级别的缓存等bootstrap() {},// 应用每次进入都会调用 mount 方法通常我们在这里触发应用的渲染方法也可以接受主应用传来的参数mount(_props) {console.log(-------- 子应用 mount --------, _props);_props.localLogin sessionStorage.setItem(localLogin, _props.localLogin);_props.roleNamesStr sessionStorage.setItem(roleNamesStr, _props.roleNamesStr);_props.token sessionStorage.setItem(token, _props.token);render(_props.container);},// 应用每次 切出/卸载 会调用的unmount方法通常在这里我们会卸载微应用的应用实例unmount(_propsy) {app.unmount();app null;router null;},update: function (_props) {render(_props.container);}});
} 3、在vite.config.js中plugins中配置乾坤插件以及其他配置参考配置如下
import qiankun from vite-plugin-qiankun;base:’/’// 静态资源访问路径。 发布到线上的时候需要改成线上服务器完整的地址 不然访问主应用的域名导致拿不到资源
plugins: [vue(),qiankun(cmdb, {useDevMode: true})
],server:{headers: {Access-Control-Allow-Origin: * // 主应用获取子应用时跨域响应头},origin: http://localhost:8991/
} 4、打包
// 修改在vite.config.js
base:’http://localhost:8991’ // 应用部署的服务器地址// 在output中添加format: umd,打包成库格式
build:{rollupOptions:{output:{format: umd}}
}三、觉得重要的地方提醒一下 1、子应用推荐 history 模式的路由 2、只有主应用需要安装乾坤 3、注意本地开发与部署到线上的子应用的地址 4、子应用需要导出bootstrap、mount、unmount钩子函数工乾坤调用 并在mount中拿到container去渲染子应用 5、子应用必须打包成 umd 格式 6、子应用部署的时候需要开启允许跨域访问配置如下
# 允许跨域请求的域, * 表示所有
add_header Access-Control-Allow-Origin *;# 允许携带Cookie
add_header Access-Control-Allow-Credentials true;# 允许请求的方式 比如常用的Restful GET/PUT/POST/DELETE
add_header Access-Control-Allow-Methods *;# 允许请求的header
add_header Access-Control-Allow-Headers *; 7、乾坤导出三个apiregisterMicroApps, start以及loadMicroApp registerMicroApps, start是搭配使用的 使用registerMicroApps, start的时候需要添加activeRule去匹配路由当匹配到activeRule值开头的路由的时候就会自动加载子应用 loadMicroApp是单独使用的 不需要activeRule去匹配路由的