qiankun单个微应用集成的demo

qiankun单个微应用集成的demo

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

0改造主应用

00创建微应用容器

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

<!-- App.vue -->
<template>
  <div id="appf">
    <img src="./assets/logo.png">
    <!-- <router-view/> -->
    <hello-world/>
    <div id='yourContainer'></div>
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue';
export default {
  name: 'App',
  components: { HelloWorld },
}
</script>
<!-- HelloWorld.vue -->
<router-link to="/chaiQiankunTest/ffff">
    test1
</router-link>
<div @click="onChangePage('/chaiQiankunTest/ffff')" >test2</div>

//定义跳转方法
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中父子组件的生命周期函数的执行顺序。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,200评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,526评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,321评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,601评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,446评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,345评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,753评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,405评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,712评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,743评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,529评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,369评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,770评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,026评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,301评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,732评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,927评论 2 336