1、在终端输入指令:vue create vue-qiankun-base,(版本vue2为例)创建一个叫 vue-qiankun-base的vue项目 ,将作为我们的主应用
2、在终端输入指令:vue create vue-qiankun-app1,vue-qiankun-app1作为子应用
3、打开主应用的集成终端,引入qiankun依赖:npm i qiankun
4、每个子应用:引入public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  /* eslint-disable */
  // 上方这一行用于eslint的忽略,因为下方代码的指向其实是不存在的,在有eslint的环境中不加入此行会报错
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}

5、打开vue-qiankun-base的 App.vue

<template>
  <div id="app">
    <!-- 父组件 -->
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
    <!-- 子组件 -->
    <div id="app-child"></div>
  </div>
</template>

6、打开vue-qiankun-base的 main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { registerMicroApps, start } from 'qiankun'

Vue.config.productionTip = false
// 挂自动档
registerMicroApps(
  [
    {
      name: 'app1', // 必选,微应用的名称,微应用之间必须确保唯一
      entry: '//localhost:8081', // 必选,微应用的入口,比如我们现在有两个子应用A和B,那么这里配置的就是他们的资源访问域名或ip
      container: '#app-child', // 必选,微应用的容器节点的选择器或者 Element 实例
      activeRule: '/app1', // 必选,微应用的激活规则。
      // loader: // 可选,loading 状态发生变化时会调用的方法
      props: { data: { router } } // 可选,主应用需要传递给微应用的数据。
    }
  ],
  {
    // 加载子应用前,可以用来加载进度条
    beforeLoad: (app) => console.log('before load', app.name),
    beforeMount: (app) => console.log('before load', app.name),
    // 加载子应用后,可以用来关闭进度条
    afterMount: (app) => console.log('after load', app.name),
    beforeUnmount: [(app) => console.log('before mount', app.name)],
    afterUnmount: [(app) => console.log('before mount', app.name)]
  }
)
// 启动 qiankun
start()
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

7、打开vue-qiankun-app1的 main.js

import './public-path'
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import routeList from './router'
import store from './store'

Vue.config.productionTip = false
Vue.use(VueRouter)
let router = null
let instance = null
function render (props = {}) {
  const { container } = props
  router = new VueRouter({
    // base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
    mode: 'history',
    routes: null
  })
  router.addRoutes(routeList)
  console.log('vue1---', router)
  instance = new Vue({
    router,
    store,
    render: (h) => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  // 可实现子应用的登录逻辑
  // const userInfo = { name: '我是独立运行时名字叫张三' } // 假设登录后取到的用户信息
  // store.commit('global/setGlobalState', { user: userInfo })
  render()
}

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap () {
  console.log('[vue] vue app bootstraped')
}
/**
 * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
 */
export async function mount (props) {
  console.log('[vue] props from main framework', props)
  render(props)
}
/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
export async function unmount (props) {
  console.log('unmount', props)
  // 首次load应用,创建子应用实例,渲染。
  // 当切到其他子应用后切回,会重新创建新的子应用实例并渲染。之前的子应用实例 qiankun 直接不要了
  // 所以说,采用registerMicroApps模式的话一定要在子应用暴露的unmount钩子里手动销毁实例,不然就内存泄漏了
  instance.$destroy()
  instance.$el.innerHTML = ''
  instance = null
}
/**
 * 可选生命周期钩子,仅使用 loadMicroApp(手动加载一个微应用) 方式加载微应用时生效
 */
// export async function update (props) {
//   console.log('update props', props)
// }

8、打开vue-qiankun-app1的 vue.config.js

const { name } = require('./package')
module.exports = {
  devServer: {
    port: 8081,
    headers: {
      'Access-Control-Allow-Origin': '*'
    }
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${name}` // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
    }
  }
}

9、打开vue-qiankun-app1的 router.js

const routeList = [
  {
    path: '/app1/',
    name: 'home1',
    component: () => import('./views/Home.vue')
  }
]
export default routeList

10、打开vue-qiankun-app1的 App.vue

<template>
  <div>
    <router-view />
  </div>
</template>

11、进入项目路径
http://localhost:8080/
http://localhost:8080/app1
http://localhost:8081/app1


笑口常开
11 声望1 粉丝