微前端解决方案-qiankun

简介

qiankun 是阿里巴巴开源的一款基于Single-SPA的微前端框架,提供了更完善的沙箱隔离、资源加载和生命周期的管理能力,适用于大型企业级前端应用。

核心

  1. 开箱即用的沙箱隔离
  • JS沙箱:通过Proxy 或with实现作用域隔离,避免全局变量污染;
  • CSS沙箱:支持动态样式隔离,防止样式冲突(Shadow或Scoped Css)
  1. 简单易用的API
  • registerMicroApps():注册子应用;
  • start():启动qiankun;
  • loadMicroApp():手动加载微应用(适用于非路由集成);
  1. 资源预加载
  • 支持子应用资源预加载,提升用户体验;
  1. 样式隔离
  • 支持Shadow或Scoped Css , 防止污染;
  1. 通信机制
  • initGlobalstate():提供主子应用通信能力(基于props或customEvent)
  1. 子应用独立运行
  • 子应用可以单独开发、部署、不影响主应用。

使用 Vue3 + TypeScript + QianKun + Vite 配置

主应用配置

1. 创建主应用

js 复制代码
npm create vite@latest main-app --template vue-ts
cd main-app
npm install qiankun

2. 修改主应用配置(vite.config.ts)

ts 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
    plugins:[vue()],
    server: {
        port:9000, // 主应用端口
        cors: true,
        origin: 'http://localhost:9000'
    },
})

3. 主应用入口文件(main.ts)

ts 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import { registerMicroApps, start } from 'qiankun'

const app createApp(App)


// 注册微应用
registerMicroApps([ 
    { 
        name: 'vue3-sub-app', // 子应用名称
        entry: '//localhost:9002', // 子应用地址 
        container: '#subapp-container', // 挂载容器 
        activeRule: '/vue3-sub-app', // 激活路由
        props: { // 传递给子应用的数据 
            mainAppData: '来自主应用的数据' 
        } 
    }
    ])
    
// 启动qiankun

start({
    sandbox: {
        experimentalStyleIsolation:true // 开启样式隔离
    }
})

4. 主应用App.vue

Vue 复制代码
<template>
  <div>
    <h1>主应用 (Vue3 + Vite)</h1>
    <router-link to="/vue3-sub-app">加载子应用</router-link>
    <div id="subapp-container"></div>
  </div>
</template>

子应用配置

1. 创建子应用

js 复制代码
npm create vite@latest sub-app --template vue-ts
cd sub-app
npm install vite-plugin-qiankun --save-dev

2. 修改子应用配置 (vite.config.ts)

ts 复制代码
import { defineConfig } from 'vite' 
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'

export default defineConfig({
    plugins: [
        vue(),
        qiankun('vue3-sub-app', { // 子应用名称,与主应用注册时一致;
            useDevMode: true
        })
    ],
    server: {
        port: 9002,
        cors: true,
        origin: 'http://localhost:9002'
    },
    base: '/vue3-sub-app'
})

3. 子应用入口文件 (main.ts)

ts 复制代码
import { createApp } from 'vue' 
import App from './App.vue'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
import type { QiankunProps } from 'vite-plugin-qiankun/es/helper';

let app:ReturnType<typeof createApp> | null = null

// 独立运行逻辑
if (!qiankunWindow._POWERED_BY_QIANKUN_) {
    createApp(App).mount('#app')
} else {
    rederWithQiankun({
        async bootstrap() {
          console.log('子应用初始化');
        },
        // 挂载时
        async mount(props:QiankunProps) {
            console.log('子应用mount', props)
            const container = props.container
              ? (props.container.querySelector('#app')
              || document.createElement('div'))
              : document.getElementById('app');
              
            if (!container) throw new Error('容器不存在');
            
            // 清空容器(避免重复挂载)
            container.innerHTML = '';
            app = createApp(App)
            app.mount(container)
        },
        // 卸载子应用
        unmount(){
            console.log('子应用unmount')
            app?.unmount()
            app = null
        },
        update(props) {
            console.log('更新子应用参数', props)
        }
    })
}

通信机制

  1. 主应用向子应用传递数据
ts 复制代码
// 主应用注册微应用时
registerMicroApps([
  {
    name: 'vue3-sub-app',
    entry: '//localhost:5174',
    container: '#subapp-container',
    activeRule: '/vue3-sub-app',
    props: { // 传递数据
      mainAppData: '来自主应用的数据',
      onGlobalStateChange: (state: any) => console.log('状态变化', state),
      setGlobalState: (state: any) => console.log('设置状态', state)
    }
  }
])
  1. 子应用接收主应用数据
ts 复制代码
// 子应用mount生命周期中
mount(props) {
  console.log('接收主应用数据:', props.mainAppData)
  
  // 监听主应用状态变化
  props.onGlobalStateChange?.((state: any) => {
    console.log('子应用监听到状态变化:', state)
  }, true)
  
  // 设置主应用状态
  props.setGlobalState?.({ user: '子应用修改的用户' })
}

路由配置

  1. 主应用路由(router.ts)
ts 复制代码
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      component: () => import('@/views/Home.vue')
    },
    {
      path: '/vue3-sub-app', // 匹配子应用路由
      component: () => import('@/views/SubAppContainer.vue'),
      children: [
          {
            path: '', // 空路径匹配
            name: 'subContainer',
            component: () => import('@/views/subContainer/index.vue'),
          },
          {
            path: ':pathMatch(.*)', // 通配符放在最后
            name: 'subContainer',
            component: () => import('@/views/subContainer/index.vue'),
          },
        ]
    }
  ]
})

export default router
  1. 子应用路由(router.ts)
ts 复制代码
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? '/vue3-sub-app' : '/'),
  routes: [
    {
      path: '/',
      component: () => import('@/views/SubHome.vue')
    },
    {
      path: '/about',
      component: () => import('@/views/SubAbout.vue')
    }
  ]
})

export default router
相关推荐
testleaf21 分钟前
前端面经整理【1】
前端·面试
好了来看下一题22 分钟前
使用 React+Vite+Electron 搭建桌面应用
前端·react.js·electron
啃火龙果的兔子23 分钟前
前端八股文-react篇
前端·react.js·前端框架
小前端大牛马29 分钟前
react中hook和高阶组件的选型
前端·javascript·vue.js
刺客-Andy29 分钟前
React第六十二节 Router中 createStaticRouter 的使用详解
前端·javascript·react.js
萌萌哒草头将军2 小时前
🚀🚀🚀VSCode 发布 1.101 版本,Copilot 更全能!
前端·vue.js·react.js
GIS之路3 小时前
OpenLayers 图层叠加控制
前端·信息可视化
90后的晨仔3 小时前
ArkTS 语言中的number和Number区别是什么?
前端·harmonyos
菜鸡爱上编程3 小时前
React16,17,18,19更新对比
前端·javascript·reactjs·react
陈龙龙的陈龙龙4 小时前
uniapp 金额处理组件
前端·javascript·uni-app