什么是微前端
-
微前端这个概念是从后端的微服务引入的
-
后端工程是一个一个服务组成的
-
前端工程(容器)太大的时候,把一部分模块或组件以工程的形式抽离出来(子应用),这一部分代码能独立使用或存在
-
在主工程(容器)中又引入子工程(子应用),并能完成正常的交互逻辑,这就是微前端
-
也可以理解成父子组件的关系,大概差不多
微前端好处
- 将一个大工程分成不同的小工程,方便维护,方便代码复用,减少bug产生
微前端实现方式
-
webComponents
-
iframe
项目中使用
-
项目中 AIS(容器),子应用(AVS)
-
微前端框架: micoapp
//main.js
import { getLoginUserInfo, selectUserPermissions } from '../../utils/api'
import microApp from '@micro-zoe/micro-app'
microApp.start({
shadowDOM: false, // 默认值false
plugins: {
modules: {
avs_web: [
{
loader(code, url) {
// console.log(url);
// if (url === 'xxx.js') {
// code = code.replace('var xx_dll=', 'window.xx_dll=')
// }
return code
},
},
],
},
},
})
<template>
<div class="child-app">
<micro-app
name="avs_web"
@unmount="handleUnmount"
:url="`${url}/AVS_WEB`"
baseroute="/AISW/avs"
:data="microAppData"
></micro-app>
</div>
</template>
<script>
import microApp, { getActiveApps, removeDomScope } from '@micro-zoe/micro-app'
export default {
name: 'index',
computed: {},
watch: {
'$route.path': {
handler(path) {
// 获取子应用appName
const appName = getActiveApps()[0]
// console.log(appName, 'appName')
this.pushState(appName, path, false, this.$route.query)
},
},
},
created() {
console.log('123')
},
data() {
return {
// url: window.location.origin,
url: process.env.NODE_ENV == 'production' ? window.location.origin : 'http://localhost:3700',
microAppData: {
authData: {
token: sessionStorage.getItem('token'),
refreshToken: sessionStorage.getItem('refreshToken'),
clientNonce: sessionStorage.getItem('clientNonce'),
cuType: sessionStorage.getItem('cuType'),
key: sessionStorage.getItem('key'),
locale: localStorage.getItem('locale'),
},
},
}
},
methods: {
handleUnmount() {
//卸载
console.log('unmount')
removeDomScope()
},
// 子应用sidebar通过pushState控制主应用跳转
pushState(appName, path, hash) {
/**
* 当子应用还未渲染,通过基座控制路由跳转,子应用在初始化时会自己根据url渲染对应的页面
* 当子应用已经渲染,则直接控制子应用进行内部跳转
*
* getActiveApps: 用于获取正在运行的子应用
*/
//获取是否有参数
if (!getActiveApps().includes(appName)) {
// child-vite 和 child-react17子应用为hash路由,这里拼接一下hash值
hash && (path += `/#${hash}`)
// 主应用跳转
this.$router.push(path)
} else {
let childPath = null
// child-vite 和 child-react17子应用是hash路由,hash值就是它的页面地址,这里单独处理
if (hash) {
childPath = hash
} else {
// path的值形式如:/app-vue2/page2,这里/app-vue2是子应用的基础路由,/page2才是页面地址,所以我们需要将/app-vue2部分删除
childPath = path.replace(/^\/avs+/, '')
!childPath && (childPath = '/') // 防止地址为空
}
let query = this.$route.query
// 主应用通过下发data数据控制子应用跳转
if (Object.keys(query).length) {
microApp.setData(appName, { path: childPath, query, type: 'update-router' })
} else {
microApp.setData(appName, { path: childPath })
}
}
},
},
}
</script>
<style scoped>
.child-app {
width: 100%;
height: 100%;
}
</style>