Skip to content

微前端 - qiankun

1. 简介

官网

  • 号称: 可能是你见过最完善的微前端解决方案🧐
  • 目前使用人数最多的微前端解决方案(社区完善)
  • 主从架构, 主应用作为基座,通过路由动态加载子应用。
  • 基于 single-spa 的微前端解决方案,来自蚂蚁金服团队。

2. 主应用

vite + vue3 项目示例

2.1. 安装
bash
npm i qiankun -S
2.2. qiankun 路由配置
js
// /src/config.js
if (import.meta.env.MODE == 'dev') {
  apps = [
    {
      name: 'app-vue3', // 子应用名称,跟package.json一致
      entry: '//localhost:9002', // dev环境 子应用入口,本地环境下指定端口
      container: '#sub-container', // 挂载子应用的dom
      activeRule: '/app-vue3', // 路由匹配规则, 子应用的路径
      props: {

      } // 主应用与子应用通信传值
    },
  ]
}else{
  apps = [
    {
      name: 'app-vue3', // 子应用名称,跟package.json一致
      entry: '/app-vue3/index.html', // 子应用入口,子应用部署位置
      container: '#sub-container', // 挂载子应用的dom
      activeRule: '/app-vue3', // 路由匹配规则, 子应用的路径
      props: {

      } // 主应用与子应用通信传值
    },
  ]
}
 
export default {
  subApps: apps
}
2.3. 生命周期配置
js
// /utils/qiankun.js
mport { registerMicroApps } from 'qiankun'
import config from '@/config'

const { subApps } = config

export function registerApps() {
  try {
    registerMicroApps(subApps, {
      beforeLoad: [
        app => {
          console.log('before load', app)
        }
      ],
      beforeMount: [
        app => {
          console.log('before mount', app)
        }
      ],
      afterUnmount: [
        app => {
          console.log('before unmount', app)
        }
      ]
    })
  } catch (err) {
    console.log(err)
  }
}
2.4. 组件化
vue
// /components/SubContainer.vue
<template>
  <div id="sub-container"></div>
</template>

<script>
import { start } from 'qiankun'
import { registerApps } from '@/utils/qiankun'
export default {
  mounted() {
    if (!window.qiankunStarted) {
      window.qiankunStarted = true
      registerApps()
      start({
        sandbox: {
          experimentalStyleIsolation: true // 样式隔离
        }
      })
    }
  }
}
</script>
2.5. router配置
js
// /src/router/index.js
import {createRouter,createWebHistory} from "vue-router"

const router = createRouter({
  history:createWebHistory(),
  routes:[
    {
      path: '/',
      component: () => import('../views/Index.vue')
    },
    {
      path: '/test',
      component: () => import('../views/test.vue')
    },
    {
      // history模式需要通配所有路由
      path: '/app-vue3/:pathMatch(.*)*',
      name: 'app-vue3',
      meta: {},
      component: () => import('@/components/SubContainer.vue')
    },
  ]
})
export default router
2.6. 主应用打包后路径

/qiankun

3. 子应用

vite + vue3 项目示例

3.1. 安装
bash
npm i vite-plugin-qiankun -S
3.2. vite.config.js 配置
js
// /vite.config.js
import qiankun from 'vite-plugin-qiankun'

export default defineConfig({
  base: '/app-vue3/', // 生产根路径
  plugins: [
    qiankun('app-vue3', {
      useDevMode: true
    })
  ],
  hot: true, // 热更新
  server: {
    port: 9002,
    cors: true,
  },
})
3.3. main.js 配置
js
// /src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import {
  renderWithQiankun,
  qiankunWindow
} from 'vite-plugin-qiankun/dist/helper'

let app

const render = (container) => {
  app = createApp(App)
  
  // 加载模块
  app.use(ElementPlus)
  app.use(store).use(router)


  app.mount(container ? container.querySelector('#app') : '#app')
}
const initQianKun = () => {
  renderWithQiankun({
    mount(props) {
      const { container } = props
      render(container)
    },
    bootstrap() {},
    unmount() {
      app.unmount()
    }
  })
}

qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render()
3.4. 路由配置
js
// /src/router/index.js
import {createRouter,createWebHistory} from "vue-router"
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

const router = createRouter({
  history: createWebHistory(
    qiankunWindow.__POWERED_BY_QIANKUN__
      ? '/app-vue3/'
      : '/'
  ),
  routes:[
    {
      path: '/',
      component: () => import('../views/Index.vue')
    },
    ...
  ]
})
3.5. 子应用打包后路径

/qiankun/app-vue3

4. 数据传递

4.1. localStorage + window (主 <-> 子)

直接存储 + 读取

4.2. Props (主 -> 子)

qiankun 路由配置里设置

  • 主应用
js
{
  name: 'app-vue3', // 子应用名称,跟package.json一致
  entry: '//localhost:9002', // dev环境 子应用入口,本地环境下指定端口
  container: '#sub-container', // 挂载子应用的dom
  activeRule: '/app-vue3', // 路由匹配规则, 子应用的路径
  props: {
    userInfo: { name: '张三' },
  } // 主应用与子应用通信传值
},
  • 子应用
js
// 子应用入口文件
export async function mount(props) {
  console.log('接收主应用参数:', props.token); 
  props.onGlobalStateChange((state) => { /* 监听全局状态 */ }); // 若包含全局状态监听
}
4.3. 全局共享 initGlobalState (主 <-> 子)

文档地址

4.4. url传参 (主 <-> 子)
4.5. 自定义事件

5. DEMO

体验DEMO

模版-quankun主应用

模版-quankun子应用

京ICP备2024093538号-1