软件教程 2025年08月6日
0 收藏 0 点赞 393 浏览 6032 个字
摘要 :

文章目录 一、主应用配置 (一)添加匹配子路由的通配路由 (二)注册和启动子路由 二、子应用配置 (一)安装和引用qiankun vite插件 (二)改造子应用入口文件 三……




  • 一、主应用配置
    • (一)添加匹配子路由的通配路由
    • (二)注册和启动子路由
  • 二、子应用配置
    • (一)安装和引用qiankun vite插件
    • (二)改造子应用入口文件
  • 三、其他需要注意的地方
    • (一)路由和服务前缀问题
    • (二)路由模式一致性
    • (三)解决history模式刷新404问题

    最近在研究vue3+vite项目接入qiankun微前端的相关内容,踩过不少坑,也总结了一些经验。今天就来给大伙分享一下这里面的关键知识点,希望能帮到正在做类似项目的小伙伴们。

    一、主应用配置

    (一)添加匹配子路由的通配路由

    在主应用里,咱们得配置能匹配所有子路由的通配路由。代码长这样:

    const routes: RouteRecordRaw[] = [
      {
        path: \'/digital-twin/:pathMatch(.*)*\', // 子路由都以/digital-twin/ 这个前缀开头
        name: \'DigitalTwin\',
        meta: {
          icon: \'ic:baseline-view-in-ar\',
          keepAlive: true,
          order: 1000,
          title: $t(\'platform.route.digitalTwinPlatform\'),
          getTabTitle: createGetTabTitle(\'/digital-twin\')
        },
        component: () => import(\'#/views/sub-app/index.vue\')
      }
    ];
    

    这里的path配置很关键,它表示所有以/digital-twin/开头的路由都会匹配到这个规则,然后会加载对应的组件。

    (二)注册和启动子路由

    1. 注册子应用:在#/views/sub-app/index.vue文件里,咱们来注册子应用。代码如下:
    // #/views/sub-app/index.vue
    <script lang=\"ts\" setup>  
      import { updatePreferences } from \'@vben/preferences\';  
      import { MicroApp } from \'#/components/micro-app\';  
      import BasicLayout from \'#/layouts/basic.vue\';  
      import { useSubApp } from \'./useSubapp\';  
    
      // 判断当前是不是全屏模式
      const route = useRoute();  
      const isFullScreen = computed(() => route.query?.fullScreen === \'1\');  
    
      // 启动子应用
      useSubApp();  
    </script>  
    <template>  
      <!-- 注册子应用的地方 -->
      <MicroApp />  
    
      <div v-if=\"isFullScreen\" class=\"sub-app\">  
        <!-- 全屏预览时子应用的挂载节点,这种情况下不需要菜单和顶栏 -->
        <div id=\"digital-twin\"></div>  
      </div>  
      <BasicLayout v-else>  
        <template #subAppCounaner>  
          <div class=\"sub-app\">  
            <!-- 正常情况下子应用的挂载节点,需要菜单和顶栏 -->
            <div id=\"digital-twin\"></div>  
          </div>  
        </template>  
      </BasicLayout>  
    </template>  
    <style lang=\"scss\">  
     .sub-app {  
        height: calc(100vh - var(--vben-header-height) - var(--vben-footer-height));  
        overflow: hidden;  
      }
      #digital-twin {
        img {
          display: inline-block;
        }
      }
    </style>
    

    这里的<MicroApp>组件就是用来注册子应用的,它会根据后续的配置去加载子应用。

    再看看#/components/micro-app里的注册逻辑:

    import { registerMicroApps } from \'qiankun\';  
    import { useAuthStore } from \'#/store/auth\';  
    import { microAppActions } from \'./micro-app-actions\';  
    
    export const MicroApp = defineComponent({  
      name: \'MicroApp\',  
      setup() {  
        registerMicroApps([  
          {  
            name: \'twinplatform\', // 给子应用取个名字,用于注册  
            // 子应用的入口地址,这里根据环境变量动态生成
            entry: `//${window.location.hostname}:${import.meta.env.VITE_DIGITAL_TWIN_PORT}${import.meta.env.VITE_BASE}digital-twin/`,  
            container: \'#digital-twin\', // 子应用挂载到id为digital-twin的节点上
            activeRule: `${import.meta.env.VITE_BASE}digital-twin`,  
            props: {  
              actions: microAppActions,  
              // 排除Vite插入的热更新脚本,避免影响子应用加载
              excludeAssetFilter: (assetUrl: string) => assetUrl.includes(\'@react-refresh\')  
            }  
          }  
        ]);  
    
        // 监听子应用的登录状态变化
        microAppActions.onGlobalStateChange((state, prev) => {  
          if (!state.isLogin && state.isLogin!== prev.isLogin) {
            useAuthStore().logout();
          }
        });
        return () => null;
      }
    });
    

    这里通过registerMicroApps方法注册了子应用,还配置了子应用的入口、挂载节点、激活规则等信息。同时,监听了子应用的登录状态变化,以便在登录失效时进行相应处理。

    1. 启动子应用:启动子应用的逻辑在./useSubapp文件里:
    import {  
      onBeforeRouteUpdate,  
      type RouteLocationNormalizedLoadedGeneric,  
      useRoute  
    } from \'vue-router\';  
    import { useTabbarStore } from \'@vben/stores\';  
    import { start } from \'qiankun\';  
    
    export const useSubApp = () => {  
      const route = useRoute();  
      onMounted(() => {  
        if (!window.qiankunStarted) {  
          window.qiankunStarted = true;  
          console.log(\'start qiankun\');  
          start({  
            sandbox: true  
          });  
        }
        // 根据当前路由更新顶部tab标签
        updateTabTitle(route);  
      });
    
      // 更新顶部tab标签的函数
      const updateTabTitle = (to: RouteLocationNormalizedLoadedGeneric) => {
        const getTabTitle = to.meta.getTabTitle as (path: string) => string;
        const title = getTabTitle(to.fullPath);
        useTabbarStore().setTabTitle(to, title);
      };
    
      // 路由切换时同步更新顶栏tab标签
      onBeforeRouteUpdate((to, from) => {
        if (to.fullPath === from.fullPath) return;
        setTimeout(() => {
          updateTabTitle(to);
        });
      });
    };
    

    这里在页面挂载时启动qiankun,并且在路由变化时更新顶部的tab标签,保证用户体验。

    还有个重要的点得注意:子应用的挂载节点可千万别选和主应用一样的节点(比如#app),也别选包含主应用(vue3)router-view组件的dom节点。不然,当子应用返回主应用时,主应用的路由可能会失效,页面就空白啦,这可就麻烦大了。

    二、子应用配置

    (一)安装和引用qiankun vite插件

    1. 安装插件:先在子应用项目里安装vite-plugin-qiankun插件,命令如下:
    npm i vite-plugin-qiankun -S
    
    1. 在vite.config.ts中引用插件:安装好之后,在vite.config.ts里引用它:
    export default defineConfig(({ mode }) => {
      ...
        return {
          ...
          plugins: [
            react(),
            // 引用插件
            qiankun(\'twinplatform\', {
              // 子应用名称
              useDevMode: true // 开发模式下启用
            })
          ]
          ...
        }
    }
    

    这个插件能帮助咱们更方便地接入qiankun微前端,配置起来也比较简单。

    (二)改造子应用入口文件

    子应用的入口文件也得改造一下,代码如下:

    import React from\'react\';  
    import ReactDOM from\'react-dom/client\';  
    import App from \'./App\';  
    import \'antd/dist/antd.css\';  
    import \'./index.less\';  
    import { actions } from \'@/utils/microAppEvent\';  
    import { renderWithQiankun, qiankunWindow, QiankunLifeCycle, QiankunProps } from \'vite-plugin-qiankun/dist/helper\';
    
    let root: ReactDOM.Root;
    // 渲染函数,用于渲染子应用
    const render = () => {
      const el = document.getElementById(\'root\') as HTMLElement;
      root = ReactDOM.createRoot(el);
      root.render(<App />);
    };
    
    // 定义qiankun的生命周期函数
    const lifecycle: QiankunLifeCycle = {
      mount(props: QiankunProps): void {
        // 实现mount逻辑,设置actions并渲染子应用
        actions.setActions(props.actions);
        render();
      },
      bootstrap(): void {
        // 实现bootstrap逻辑,在控制台打印提示信息
        console.log(\'react app bootstraped\');
      },
      unmount(props): void {
        // 实现unmount逻辑,卸载子应用
        console.log(\'react app unmount\');
        root?.unmount();
      },
      update(props: QiankunProps): void {
        // 实现update逻辑
      }
    };
    
    // 使用renderWithQiankun方法启动子应用
    renderWithQiankun(lifecycle);
    
    // 独立运行逻辑,如果不是在qiankun环境下,直接渲染子应用
    if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
      render();
    }
    

    这里通过renderWithQiankun方法来启动子应用,并且实现了qiankun的生命周期函数。注意,必须要用这个方法,不然会提示找不到入口生命周期钩子函数。

    三、其他需要注意的地方

    (一)路由和服务前缀问题

    1. 子应用和主应用的服务前缀得保持一致。比如说,主应用服务前缀是a/b,那子应用的服务前缀也得包含a/b。像这样:
    // history模式
    // 子应用地址:localhost:8666/a/b/home
    // 主应用地址:localhost:8999/a/b/child-sub1/home
    // 子应用必须包含主应用的服务前缀,不然registerMicroApps注册的子应用激活规则:activeRule: `child-sub1`,就没法正常配置激活子应用
    // 必须写成:activeRule: `{主应用服务前缀}/child-sub1`
    
    1. 如果有服务前缀,还得同步设置路由的baseurl
    // react:
    ...
    <BrowserRouter basename={服务前缀}>
    ...
    </BrowserRouter>
    ...
    
    // vue3
    const router = createRouter({
      history: `服务前缀`,
      // 应该添加到路由的初始路由列表。
      routes,
      scrollBehavior: (to, _from, savedPosition) => {
        if (savedPosition) {
          return savedPosition;
        }
        return to.hash? { behavior:\'smooth\', el: to.hash } : { left: 0, top: 0 };
      },
      // 是否应该禁止尾部斜杠。
      // strict: true,
    });
    

    (二)路由模式一致性

    主应用和子应用的路由模式也得保持一致,要么都用history模式,要么都用hash模式。要是不一致,可能会出现各种奇怪的问题。

    (三)解决history模式刷新404问题

    history模式下,刷新页面可能会出现404错误。这时候可以通过nginx配置来解决,配置如下:

    location /a/b {
      try_files $uri $uri/ /a/b/index.html; # 找不到资源时,返回主应用首页
      add_header \'Access-Control-Allow-Origin\' \'*\';
      add_header \'Access-Control-Allow-Methods\' \'GET, POST, OPTIONS\';
      add_header \'Access-Control-Allow-Headers\' \'Origin, Content-Type, Accept, Authorization\';
    }
    

    这里要注意,子应用刷新时,别返回子应用的首页(index.html),得返回主应用的index.html。不然在子应用页面刷新时,可能会丢失主应用的内容。最好把主应用和子应用部署在同一个域名下,这样能减少很多麻烦。

    以上就是vue3+vite项目接入qiankun微前端的关键要点啦。大伙在实际项目中遇到问题,欢迎一起讨论,互相学习!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6833.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

269
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

107
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

683
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

338
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

371
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

843
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号