qiankun(一):应用接入

576 阅读2分钟

一、qiankun版本

v2.7.2

二、主应用(基座)

若依vue2版本

三、子应用

一个只有两个页面的人脸识别项目

四、主应用改造

1.主应用安装qiankun框架

npm i qiankun -S

2.main.js中引入qiankun的注册应用函数,对子应用进行注册

import { registerMicroApps } from 'qiankun';

registerMicroApps([{

    name: 'face-recognition', // 子应用名称,与子应用package.json中的name一致

    entry: 'http://localhost:8080', //入口地址

    container: '#qiankunContainer', //父应用提供的渲染子应用的容器

    // activeRule: '/portal' //指定激活访问子应用的路由,下面的写法也可以

    activeRule: location => location.pathname.startsWith('/portal')
}]);

五、子应用改造

1.子应用无需下载qiankun

2.子应用main.js暴露生命周期供主应用加载时调用

let instance = null;

function render() {
  // 挂载应用
  instance = new Vue({
    router,
    render: h => h(App)
  }).$mount('#sub');//*注意:这有个坑,子应用挂载的节点不要与基座里的重复,自己单独起个id
}
// 独立运行时
//使用window.__POWERED_BY_QIANKUN__变量判断子应用是独立运行还是在基座运行
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}
/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
  console.log('微应用初始化');
}
/**
 * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
 */
export async function mount(props) {
  console.log('微应用mount');
  render();
}
/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
export async function unmount(props) {
  console.log('微应用unmount');
  instance.$destroy();
}

3.子应用显示在基座时字体图标不显示,及打包配置修改

// vue.config.js
chainWebpack: (config) => {
    config.module
      .rule('fonts')
      .test(/.(ttf|otf|eot|woff|woff2)$/)
      .use('url-loader')
      .loader('url-loader')
      .tap(options => {
        options = {
          // limit: 10000,
          name: '/static/fonts/[name].[ext]'
        };
        return options;
      })
      .end();
  },

  configureWebpack: {
    output: {
      library: `face-recognition`,
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${packageName}`
    }
  }

4. 子应用图片在基座不显示

//根目录创建 public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

//在main.js中引入

import './public-path';

*六、主应用的额外改造

image.png

由于想实现如上图效果,在主应用点击左侧菜单,右侧部分渲染子应用对应的页面,所以需要如下改造

1.修改子应用路由

export const constantRoutes = [
  {
    path: '',
    component: container,
    name: 'container',
    redirect: '/faceRecog',
    children: [
      {
        path: '/faceRecog',
        name: 'faceRecog',
        component: faceRecog
      },
      {
        path: '/faceAlarm',
        name: 'faceAlarm',
        component: faceAlarm
      }
    ]
  }
];

export default new Router({

  mode: 'history', // 设置为history模式

  base: '/portal', // base设置为portal 也就是访问 http://xx.xx.xx.xx/portal相当与访问ttp://xx.xx.xx.xx/

  routes: constantRoutes

});

2.根据子应用的路由,配置主应用的菜单

image.png

3.主应用创建一个portal组件用于提供渲染子应用的容器

<template>
  <div>
    //对应registerMicroApps函数中的container
    <div id="qiankunContainer" />
  </div>
</template>
<script>
import { start } from 'qiankun';
export default {
  mounted() {
    if (!window.qiankunStarted) {
      window.qiankunStarted = true;
      start();
    }
  }
};

</script>

4.主应用在构建路由tree的时候,对子应用的路由单独处理,以若依的permission.js为例

遇到以portal开头的路由,即子应用的路由,直接走portal组件

image.png

5.此时点击了菜单,进入portal组件,组件的mounted内调用了qiankun的start函数,将子应用渲染到id为'qiankunContainer'的dom内

七、遇到的一些坑

1.由于若依给router-view加了key,使得组件都不会复用,所以对key增加判断,是portal组件复用,避免子应用渲染异常

image.png

2.子应用也有左侧菜单,当在基座内渲染时,怎样隐藏掉左侧菜单

image.png

使用window.__POWERED_BY_QIANKUN__变量判断是否在基座运行,对菜单显示隐藏即可