微前端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(); }})();