乐趣区

关于前端:微前端microApp

微前端 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>

生命周期列表

  1. created
    <micro-app> 标签初始化后,加载资源前触发。
  2. beforemount
    加载资源实现后,开始渲染之前触发。
  3. mounted
    子利用渲染完结后触发。
  4. unmount
    子利用卸载时触发。
  5. 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();}
})();
退出移动版