共计 2995 个字符,预计需要花费 8 分钟才能阅读完成。
微前端 microApp 实际
微前端的概念是由 ThoughtWorks 在 2016 年提出的,它借鉴了微服务的架构理念,外围在于将一个宏大的前端利用拆分成多个独立灵便的小型利用,每个利用都能够独立开发、独立运行、独立部署,再将这些小型利用交融为一个残缺的利用,或者将本来运行已久、没有关联的几个利用交融为一个利用。微前端既能够将多个我的项目交融为一,又能够缩小我的项目之间的耦合,晋升我的项目扩展性,相比一整块的前端仓库,微前端架构下的前端仓库偏向于更小更灵便。
我的项目革新背景
因我的项目须要要做一个大数据交融平台,次要功能模块包含用户治理、流程治理、大数据治理算子利用,根底组件等混合形成的交融平台;公司目前曾经存在用户治理、流程治理等成品;根本主内容也是和这些产品的性能统一,主框架只是管制着导航和头部信息;因而心愿可能抱着复用的形式,更快的进行交融接入。
前端风行的微服务框架比对
参数 | singlespa | qianku | microapp |
---|---|---|---|
开发成本 | 开发成本高 | 开发成本中 | 开发成本高 |
保护老本 | 中 | 中 | 中 |
技术栈 | 不限技术栈 | 不限技术栈 | 不限技术栈 |
实现难易 | 实现难 | 实现中 | 实现简略 |
原理 | 监听 url change 事件 | 监听 url change 事件 | WebComponent |
通过比照,目前感觉 micro-app 应用简略,将所有性能都封装到一个类 WebComponent 组件中,从而实现在基座利用中嵌入一行代码即可渲染一个微前端利用。同时 micro-app 还提供了 js 沙箱、款式隔离、元素隔离、预加载、数据通信、动态资源补全等一系列欠缺的性能。子利用根本不须要过多的进行我的项目革新,绝对应用老本更低
对接阐明
- 主框架依赖包引入
import microApp from '@micro-zoe/micro-app'
- 主利用启动(并能够进行全局配置)
microApp.start({
plugins: {
global: [{loader(code, url, options) { // 必填
console.log('全局插件')
return code
}
}],
}
}
})
// 相干参数
microApp.start({
inline: true, // 默认值 false
destroy: true, // 默认值 false
disableScopecss: true, // 默认值 false
disableSandbox: true, // 默认值 false
shadowDOM: true, // 默认值 false
ssr: true, // 默认值 false
})
- 配置组件节点
<micro-app
style="height: 100%;"
name='appnameUserCenter'
:url='url'
:data='microAppData'
@created='handleCreate'
@beforemount='handleBeforeMount'
@mounted='handleMount'
@unmount='handleUnmount'
@error='handleError'
@datachange='handleDataChange'
></micro-app>
生命周期列表
- created
<micro-app> 标签初始化后,加载资源前触发。 - beforemount
加载资源实现后,开始渲染之前触发。 - mounted
子利用渲染完结后触发。 - unmount
子利用卸载时触发。 - error
子利用渲染出错时触发,只有会导致渲染终止的谬误才会触发此生命周期。
- 路由匹配设置(含糊匹配,倡议主利用 history,微利用 hash 模式,)
{
path: '/mainPanel',
name: 'mainPanel',
component: mainPanel,
children:[
{
path: '/mainPanel/dataCenter*',
name: 'dataCenter',
component:()=>dataCenter},
{
path: '/mainPanel/userCenter*',
name: 'userCenter',
component:()=>userCenter},
]
}
- 主微框架通信
microMenu(appName, path, hash) {if (!getActiveApps().includes(appName)) {
path = '/mainPanel' + path+'/'
// 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(/^\/app-[^/]+/, '')
!childPath && (childPath = '/') // 避免地址为空
}
// 主利用通过下发 data 数据管制子利用跳转
microApp.setData(appName, { path: childPath})
}
}
- 微框架及其路由跳转
(function () {
let app = null;
// 创立 vue 实例
const createVue = function () {
app = new Vue({
el: "#app",
router,
store,
render: (h) => h(App),
});
};
// 与基座进行数据交互
const handleMicroData = function (callBack) {window.microApp.addDataListener((data) => {callBack(data);
});
};
// 微前端环境下,注册 mount 和 unmount 办法
if (window.__MICRO_APP_ENVIRONMENT__) {let {token} = window.microApp.getData();
token && setToken(token);
console.log("data-center token:", token);
window[`micro-app-${window.__MICRO_APP_NAME__}`] = {
// 微前端挂载
mount: () => {createVue();
handleMicroData((data) => {
// 交互操作
store.dispatch("settings/changeSetting", {
key: "microFlag",
value: true,
});
console.log("data-center addDataListener:", data);
router.push(data.path);
});
},
// 微前端卸载
unmount: () => {app.$destroy();
app.$el.innerHTML = "";
app = null;
console.log("微利用 child-vue2 卸载了");
},
};
} else {
// 非微前端环境间接渲染
createVue();}
})();