qiankun 微前端应用实践

微前端技术栈 Vue3 + vite + ts

基座配置

基座采用是的 Vue3 + vite + ts,只负责导航的渲染和登录态的下发,为子应用提供一个挂载的容器div,

npm i qiankun

qiankun这个库只需要在基座引入,在main.ts 中注册子应用,为了方便管理,我们将子应用的配置都放在:/src/qiankun.js下

import {
    
     registerMicroApps, addGlobalUncaughtErrorHandler, start } from 'qiankun';
import router from './router'
// 注册子应用
registerMicroApps([
  {
    
    
    // 子应用名称,name值必须与子应用vite.config.ts文件中plugins属性qiankun的第一个参数值一致
    name: 'subApp',
    // 默认会加载这个路径下的html,解析里面的js
    entry: '//localhost:5050/',
    // 加载的容器(微应用会显示到这个容器里面,一定要保证主应用中有这个容器)
    container: '#subAppContainerVue3',  // 和app.vue配置的节点一致
    // 匹配的路由
    activeRule: '/gosubsystem', // 访问:http://localhost:5174/juminronghe
    props: {
    
    
        mag: '我是主应用main', // 主应用向微应用传递参数
    },
  },
  {
    
    
    // 子应用名称,name值必须与子应用vite.config.ts文件中plugins属性qiankun的第一个参数值一致
    name: 'lmsApp',
    // 默认会加载这个路径下的html,解析里面的js
    entry: '//localhost:5000/',
    // 加载的容器(微应用会显示到这个容器里面,一定要保证主应用中有这个容器)
    container: '#subAppContainerVue3',  // 和app.vue配置的节点一致
    // 匹配的路由
    activeRule: '/lmsApp', 
    props: {
    
    
        mag: '我是主应用main', // 主应用向微应用传递参数
        router    // 主路由下发到子路由,子应用路由跳转使用主应用路由实例跳转(需要跳转的路由要在主应用里注册)
    },
  }
],
{
    
    
  beforeLoad: app => {
    
    
    console.log('before load app.name====>>>>>', app.name)
  },
  beforeMount: [
    app => {
    
    
      console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
    },
  ],
  afterMount: [
    app => {
    
    
      console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name);
    }
  ],
  afterUnmount: [
    app => {
    
    
      console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
    },
  ],
});
// 启动 qiankun
// start({
    
    
//     prefetch:'all', // 预加载
//     sandbox: {
    
    
//         experimentalStyleIsolation: true, //   开启沙箱模式,实验性方案
//     },
// });
// 添加全局异常捕获
addGlobalUncaughtErrorHandler((event) => {
    
    
  // console.error(event);
  const {
    
     message: msg } = event;
  // 加载失败时提示
  if (msg && msg.includes("died in status LOADING_SOURCE_CODE")) {
    
    
    // message.error("微应用加载失败,请检查应用是否可运行");
    console.log("微应用加载失败,请检查应用是否可运行-乾坤插件是否正常")
  }
});

然后在src/main.ts中引入

import './qiankun.js';  

如何在主应用的某个路由页面加载微应用

必须保证微应用加载时主应用这个路由页面也加载了
主应用注册这个路由时给 path 加一个 *,注意:如果这个路由有其他子路由,需要另外注册一个路由,仍然使用这个组件即可

 {
    
    
    path: '/portal/*',
    name: 'portal',
    component: () => import('../views/Portal.vue'),
  },

Portal.vue

<template>
 <div id="subAppContainerVue3"></div>
</template>
  
<script lang="ts" setup  name="merchantsRuquest">
// import start from "@/qiankun/index.js";
import {
    
     start } from 'qiankun'
// import { registerApps } from '@/qiankun/index.js'
onMounted(()=>{
    
    
    if (!window.qiankunStarted) {
    
    
            window.qiankunStarted = true
            // registerApps()
            start({
    
    
                sandbox: {
    
    
                    experimentalStyleIsolation: true // 样式隔离
                }
            })
        }
})
// export default {
    
    
//     mounted() {
    
    
      
//     }
// }
</script>

主应用路由配置

 {
    
    
          path: '/lmsApp/*',   // 注意和registerMicroApps 注册子应用的activeRule匹配
          name: 'lmsApp',
          meta: {
            title: "子应用菜单管理",
            icon: "car-outlined",
            isFull: false,
            isKeepAlive: true,
            isHide: false
          },
          children: [
            {
              name: 'xxxxx',
              path: '/lmsApp/xxxx/xxxxx',
              component: () => import('@/views/portal.vue'),
              meta: {
                title: '子应用菜单下的二级菜单',
                icon: '',
                isKeepAlive: false
              }
            },
           
          ]
        },

这样,基座就算配置完成了。项目启动后,子应用将会挂载到主应用中

子应用配置

安装vite-plugin-qiankun

npm i vite-plugin-qiankun --save-dev

修改vite.config.ts
import qiankun from 'vite-plugin-qiankun' 引入乾坤插件
plugins: [ vue(), qiankun('app-vue3', { useDevMode: true }) ], 使用

在子应用main.ts 里引用qiankun

import {
    
    
  renderWithQiankun,
  qiankunWindow,
  type QiankunProps
} from 'vite-plugin-qiankun/dist/helper'
let app: any

const render = (container?: any, routers?: any) => {
    
    
  app = createApp(App)
  Object.keys(Icons).forEach((key) => {
    
    
    app.component(key, Icons[key as keyof typeof Icons])
  })
  app.use(pinia)
  app.use(print)
  app.use(Antd)
  app.use(directives)
  app.config.globalProperties.$routers = routers
  app.use(router).mount(container ? container.querySelector('#app') : '#app')
}

const initQianKun = () => {
    
    
  renderWithQiankun({
    
    
    mount(props) {
    
    
      // localStorage.lalal = 111111
      console.log(props.router, '获取主应用传递数据')
      sessionStorage.latoutStatus = false
      const {
    
     container, router } = props

      render(container, router)
    },
    bootstrap() {
    
     },
    unmount() {
    
    
      app.unmount()
    },
    update: function (props: QiankunProps): void | Promise<void> {
    
    
      throw new Error('Function not implemented.')
    }
  })
}
// console.log(qiankunWindow.__POWERED_BY_QIANKUN__, '90')
qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render()

由于路由模式为history,需要匹配子应用的入口规则,修改src/router/index

import {
    
     qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
const router = createRouter({
    
    
  history: createWebHistory(
    qiankunWindow.__POWERED_BY_QIANKUN__
      ? '/lmsApp/'
      : '/'
  ),
  routes
})

至此,本地运行的所有配置全部修改完

猜你喜欢

转载自blog.csdn.net/weixin_45653441/article/details/134877301