qiankun单个微应用集成的demo

qiankun单个微应用集成的demo

这里改造的主应用和微应用都是Vue的项目,但是qiankun本身不限制技术栈,不同子应用可以是不同的技术栈,并且为了简单,方便大家搭建,这里的主微应用全部都是利用Vue-cli脚手架生成的。

0改造主应用

00创建微应用容器

微应用容器用于承载微应用,渲染显示微应用







    test1

test2
//定义跳转方法 onChangePage(url){ console.log(url) this.routerGo(url, '我喜爱的男明星') }, routerGo(href = '/', title = null, stateObj = {}) { window.history.pushState(stateObj, title, href); }

出于简单考虑,这里没有使用router-view,防止因为路由的改变,主应用的渲染出现变化,现在这样做方便微应用挂载之后进行对比。

01注册微应用

微应用的注册点可以自己选择,既可以在main.js中进行注册,那么在应用启动时就会执行相应的生命周期函数,还可以在路由守卫中,命中路由之后进行注册,demo中选择在路由命中后动态的注册微应用。

//router/index.js
import { registerMicroApps, start } from "qiankun"

router.beforeEach((to, from, next) => {
  if (to.path.includes('/chaiQiankunTest/ffff')) {
    registerMicroApps(
      [
          {
              name: "chai-project",//这里的name一定要和微应用这配置的output中的library相互对应,因为    name是主应用找到微应用对外暴露的生命周期函数的主要凭证
              entry: "//localhost:8080",//这是微应用的入口地址
              container: '#yourContainer',//这是在主应用中微应用的渲染承载容器
              activeRule: "/chaiQiankunTest/ffff"//这是进行路由监听,一旦匹配,就会加载微应用并进行挂载,这里也要主要在微应用中需要设置路由base的时候要相互对应,后面会提到
          }
      ],
      {
          beforeLoad: [
              app => {
                  console.log("before load", app);
              }
          ], // 挂载前回调
          beforeMount: [
              app => {
                  console.log("before mount", app);
              }
          ], // 挂载后回调
          afterUnmount: [
              app => {
                  console.log("after unload", app);
              }
          ] // 卸载后回调
      }
    )
    start();
  }
  next();
})

01改造微应用

00导出 qiankun 主应用所需要的三个生命周期钩子函数

这里主要修改的就是微应用的入口文件main.js,由于代码不多,这里直接将整个文件代码贴出来

//main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import routes from './router'
import axios from 'axios'
import Router from 'vue-router'
import './public-path'

let router = null;
let instance = null;

Vue.config.productionTip = false
Vue.use(Router);

/**
 * 渲染函数
 * 两种情况:主应用生命周期钩子中运行 / 微应用单独启动时运行
 */
function render (props) {
  // 在 render 中创建 VueRouter,可以保证在卸载微应用时,移除 location 事件监听,防止事件污染
  router = new Router({
    // 运行在主应用中时,添加路由命名空间 /chaiQiankunTest/ffff,这和主应用中注册微应用时的activeRule相互对应
    base: window.__POWERED_BY_QIANKUN__ ? 'chaiQiankunTest/ffff' : '/',
    mode: 'history',
    routes
  });

  // 挂载应用
  instance = new Vue({
    router,
    render: (h) => h(App),
    beforeCreate () {
      window.util = {}
      window.util.$http = axios.create({
        timeout: 1000 * 50,
        withCredentials: true
      })
    }
  }).$mount('#app');
}

// 独立运行时,直接挂载应用
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap () {
  console.log('mscrtApp bootstraped');
}

/**
 * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
 */
export async function mount (props) {
  console.log('mscrtApp mount', props);
  render(props);
}

/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
export async function unmount () {
  console.log('mscrtApp unmount');
  instance.$destroy();
  instance = null;
  router = null;
}
//public-path.js
if (window.__POWERED_BY_QIANKUN__) {
    // 动态设置 webpack publicPath,防止资源加载出错
    // eslint-disable-next-line no-undef
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

这里面可能还牵扯到router/index.js的改造,将VueRouter的创建迁移到render中,具体的作用是可以保证在卸载微应用时,移除 location 事件监听,防止事件污染。

01配置 webpack

主要的目的是使 main.js 导出的生命周期钩子函数可以被 qiankun 识别获取 。

//webpack.base.conf.js
output: {
    // 微应用的包名,这里与主应用中注册的微应用名称一致。这个名字也就是package.json中的name
    library: 'chai-project',
    // 将你的 library 暴露为所有的模块定义下都可运行的方式
    libraryTarget: 'umd',
    // 按需加载相关,设置为 webpackJsonp_VueMicroApp 即可
    jsonpFunction: `webpackJsonp_chai-project`
  },
//webpack.base.conf.js中的devServer对象中需要加入下面这个配置,这样主应用在fatch微应用静态资源时会出现跨域的问题
disableHostCheck: true,
headers: {
    'Access-Control-Allow-Origin': '*'
}

如果没有设置这个跨域的设置,那么就可能出现跨域问题,

跨域问题.jpg

02demo演示

主应用界面初始化

主应用界面.jpg

test1和test2是两个触发注册微应用的按钮,功能一样,点击test1可以得到:

qiankundemo演示.jpg

此时成功加载微应用,并且DOM结构为:

加载微应用后的dom结构.jpg

主应用和微应用的生命周期函数的执行顺序为

挂载子应用时的生命周期钩子函数主子应用的执行顺序.jpg

在点击回退到主应用的页面之后,主微应用的生命周期钩子函数的执行顺序为

子应用unmount时的主子应用生命周期函数的执行顺序.jpg

总结

到这,Vue技术栈的主应用和微应用的集成Demo算是基本完成,这里只是最基础的一个集成示例,它们的钩子函数的执行顺序有些类似Vue中父子组件的生命周期函数的执行顺序。

你可能感兴趣的:(qiankun单个微应用集成的demo)