微前端——qiankun

2024-03-26 13:04
文章标签 前端 frontend qiankun

本文主要是介绍微前端——qiankun,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、微前端

微前端是指存在于浏览器中的微服务,其借鉴了后端微服务的架构理念,将微服务的概念扩展到前端。即将一个大型的前端应用拆分为成多个模块,每个微前端模块可以有不同的团队开发并进行管理,且可以自主选择框架,以及有自己的仓库,可以独立部署上线。
(1)未使用微服务之前的项目架构
在这里插入图片描述
(2)使用微服务之前的项目架构
在这里插入图片描述

二、微前端的优点

团队自治

在公司里面,一般团队都是按照业务划分的,在没有微前端的时候,如果几个团队维护一个项目肯定会遇到一些冲突,比如合并代码的冲突,上线时间的冲突等。应用了微前端之后,就可以将项目根据业务模块拆分成几个小的模块,每个模块都有不同的团队去维护,单独开发,单独部署上线,这样团队可以实现自治,减少甚至不会出现和其他团队冲突的情况。

兼容老项目

如果公司中存在古老的或者其他巨石项目,但是又不想用旧的技术栈去为维护,选择使用微服务的方式去拆分项目是一个很好的选择。

跨技术栈

如果我们的微前端系统重需要新增一个业务模块时,只需要单独的新建一个项目,至于项目采用技术栈,完全可以有团队自己去定义,即使和其他模块用不同的技术栈也不会有任务问题。
在这里插入图片描述

三、微前端示例

需求:做一个vue2的微前端,以vue2为主应用,其他技术栈为子应用。

step1:创建主应用(基座)
vue create main-app
step2:主应用安装qiankun
npm install qiankun
step3:创建main-app.js
 // 1.要加载的子应用列表
const microApps = [{name: 'test-web', // 子应用名称entry: 'http://localhost:8081/', //子应用运行地址activeRule: '/test-web',//匹配的路由sanbox: true //解决css冲突},
]const apps = microApps.map(item => {return {...item,container: '#test-web', // 子应用挂载的divprops: {routerBase: item.activeRule // 下发基础路由}}
})
export default apps
step4:引入main-app.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
import { registerMicroApps, start } from 'qiankun';
import mainApp from './main-app'
// 2.注册子应用
registerMicroApps(mainApp, {beforeLoad: app => {console.log('before load app.name====>>>>>', app.name)},beforeMount: [app => {console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name)}],afterMount: [app => {console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name)}],afterUnmount: [app => {console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name)}]
})
// 3.启动微服务
start()
new Vue({router,store,render: h => h(App)
}).$mount('#app')
step5:配置主应用路由

在main-app/src文件夹下添加qiankun文件夹,并且添加index.vue文件作为入口文件

<template><div id="test-web"></div>
</template><script>
export default {mounted() {},
};
</script>
<style>
#test-web {width: 100%;height: 100%;
}
</style>

router.js

import Vue from "vue";
import VueRouter from "vue-router";
import HomeView from "../views/HomeView.vue";
import layout from '../views/qiankun/index.vue'
Vue.use(VueRouter);const routes = [{path: "/",name: "home",component: HomeView,},{path: "/about",name: "about",// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () =>import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),},{path: "/test-web/*",meta: 'test-web',component: layout}
];const router = new VueRouter({mode: "history",base: process.env.BASE_URL,routes,
});export default router;
step6:创建子应用
vue create sub-app
step7:修改子应用main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
//引入public-path.js
// import "../public-path";Vue.config.productionTip = false// new Vue({
//   router,
//   store,
//   render: h => h(App)
// }).$mount('#app')// 判断是否在qiankun的运行环境下,非qiankun运行环境下单独运行
if (window.__POWERED_BY_QIANKUN__) {// eslint-disable-next-line no-undef__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}let instance = null;
function render(props = {}) {const { container } = props;console.log(11111111111111, window.__POWERED_BY_QIANKUN__, '字段值')instance = new Vue({router,store,render: h => h(App),}).$mount(container ? container.querySelector('#app') : '#app', true); //开启沙箱
}if (!window.__POWERED_BY_QIANKUN__) {console.log('独立运行')render();
}function storeTest(props) {props.onGlobalStateChange &&props.onGlobalStateChange((value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev),true,);props.setGlobalState &&props.setGlobalState({ignore: props.name,user: {name: props.name,},});
}// 各个生命周期,只会在微应用初始化的时候调用一次,下次进入微应用重新进入是会直接调用mount钩子,不会再重复调用bootstrap
export async function bootstrap() {console.log('111111111111 [vue] vue app bootstraped');
}
// 应用每次进入都会调用mount方法,通常在这里触发应用的渲染方法
export async function mount(props) {console.log('11111111111 [vue] props from main framework', props);storeTest(props);render(props);
}
// 应用每次切除/注销会调用的方法,在这里会注销微应用的应用实例
export async function unmount() {instance.$destroy();instance.$el.innerHTML = '';instance = null;
}
step8:注册子应用路由
<!--子应用页面代码-->
<template><div class="sub-app">我是子应用页面11</div>
</template><style lang="scss" scoped>
.sub-app {cursor: pointer;background-color: aqua;
}
</style>
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'Vue.use(VueRouter)const routes = [{path: '/',name: 'home',component: HomeView},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path: '/test',name: 'test',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/subapp/index.vue')},{path: '/testtwo',name: 'testtwo',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/subapp/two.vue')},
]const router = new VueRouter({mode: 'history',base: window.__POWERED_BY_QIANKUN__ ? '/test-web/' : '/',routes
})export default router
step9:修改vite.config.js
const { name } = require('./package.json')module.exports = {publicPath: '/', // 打包相对路径devServer: {port: 8081, // 运行端口号headers: {'Access-Control-Allow-Origin': '*' // 防止加载时跨域}},chainWebpack: config => config.resolve.symlinks(false),configureWebpack: {output: {library: `${name}-[name]`,libraryTarget: 'umd', // 把微应用打包成 umd 库格式// webpack5.0以上版本使用如下字段chunkLoadingGlobal: `webpackJsonp_${name}`}}
}
step10:修改引用主应用和子应用

主应用的App.vue添加如下代码

<template><div id="app"><div id="nav"><router-link to="/test-web/test">sub-vue1</router-link> |<router-link to="/test-web/testtwo">sub-testtwo</router-link> |</div><router-view /></div>
</template><style lang="scss">
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}#nav {padding: 30px;a {font-weight: bold;color: #2c3e50;&.router-link-exact-active {color: #42b983;}}
}
</style>
step11:项目目录

在这里插入图片描述
在这里插入图片描述

四、微前端的问题

样式隔离

在这里插入图片描述
具体方案:在基座中复写并监听history.pushState()方法并做相应的跳转逻辑
在这里插入图片描述

公共依赖加载

在这里插入图片描述

全局状态管理

一般来说,各个子应用是通过业务来划分的,不同业务线应该降低耦合度,尽量去避免通信,但是如果涉及到一些公共的状态或者操作,qinakun也是支持的。
qiankun提供了一个全局的GlobalState来共享数据,基层初始化之后,子应用可以监听到这个数据的变化,也能提交到这个数据。
在这里插入图片描述

这篇关于微前端——qiankun的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/848601

相关文章

使用vscode搭建pywebview集成vue项目实践

《使用vscode搭建pywebview集成vue项目实践》:本文主要介绍使用vscode搭建pywebview集成vue项目实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录环境准备项目源码下载项目说明调试与生成可执行文件核心代码说明总结本节我们使用pythonpywebv

使用Python和Tkinter实现html标签去除工具

《使用Python和Tkinter实现html标签去除工具》本文介绍用Python和Tkinter开发的HTML标签去除工具,支持去除HTML标签、转义实体并输出纯文本,提供图形界面操作及复制功能,需... 目录html 标签去除工具功能介绍创作过程1. 技术选型2. 核心实现逻辑3. 用户体验增强如何运行

CSS 样式表的四种应用方式及css注释的应用小结

《CSS样式表的四种应用方式及css注释的应用小结》:本文主要介绍了CSS样式表的四种应用方式及css注释的应用小结,本文通过实例代码给大家介绍的非常详细,详细内容请阅读本文,希望能对你有所帮助... 一、外部 css(推荐方式)定义:将 CSS 代码保存为独立的 .css 文件,通过 <link> 标签

使用Vue-ECharts实现数据可视化图表功能

《使用Vue-ECharts实现数据可视化图表功能》在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所... 目录前言为什么选择 vue-ECharts?1. 基于 ECharts,功能强大2. 更符合 Vue

Vue中插槽slot的使用示例详解

《Vue中插槽slot的使用示例详解》:本文主要介绍Vue中插槽slot的使用示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、插槽是什么二、插槽分类2.1 匿名插槽2.2 具名插槽2.3 作用域插槽三、插槽的基本使用3.1 匿名插槽

springboot+vue项目怎么解决跨域问题详解

《springboot+vue项目怎么解决跨域问题详解》:本文主要介绍springboot+vue项目怎么解决跨域问题的相关资料,包括前端代理、后端全局配置CORS、注解配置和Nginx反向代理,... 目录1. 前端代理(开发环境推荐)2. 后端全局配置 CORS(生产环境推荐)3. 后端注解配置(按接口

Vue 2 项目中配置 Tailwind CSS 和 Font Awesome 的最佳实践举例

《Vue2项目中配置TailwindCSS和FontAwesome的最佳实践举例》:本文主要介绍Vue2项目中配置TailwindCSS和FontAwesome的最... 目录vue 2 项目中配置 Tailwind css 和 Font Awesome 的最佳实践一、Tailwind CSS 配置1. 安

CSS3 布局样式及其应用举例

《CSS3布局样式及其应用举例》CSS3的布局特性为前端开发者提供了无限可能,无论是Flexbox的一维布局还是Grid的二维布局,它们都能够帮助开发者以更清晰、简洁的方式实现复杂的网页布局,本文给... 目录深入探讨 css3 布局样式及其应用引言一、CSS布局的历史与发展1.1 早期布局的局限性1.2

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs

CSS引入方式和选择符的讲解和运用小结

《CSS引入方式和选择符的讲解和运用小结》CSS即层叠样式表,是一种用于描述网页文档(如HTML或XML)外观和格式的样式表语言,它主要用于将网页内容的呈现(外观)和结构(内容)分离,从而实现... 目录一、前言二、css 是什么三、CSS 引入方式1、行内样式2、内部样式表3、链入外部样式表四、CSS 选