记录–微前端qiankun接入vue2&vue3项目

  • 记录–微前端qiankun接入vue2&vue3项目已关闭评论
  • 19 次浏览
  • A+
所属分类:Web前端
摘要

点赞 + 收藏 === 学会🤣🤣🤣官方文档对应路由模式分别是hash和history主应用是基于vue3开发的一个门户网站,仅有登录以及门户列表。


🧑‍💻 写在开头

点赞 + 收藏 === 学会🤣🤣🤣

官方文档

接入vue2项目和vue3项目

对应路由模式分别是hashhistory

主应用

主应用是基于vue3开发的一个门户网站,仅有登录以及门户列表。

基于路由配置方式

通过将微应用关联到一些 url 规则的方式,实现当浏览器 url 发生变化时,自动加载相应的微应用的功能。

  • 安装qiankun

    npm i qiankun -S # 或者 yarn add qiankun

  • 在主应用中注册微应用以及对应配置

    新建qiankun文件夹,包含一个config.jsindex.js

  • config下面存放微应用的配置信息,代码如下:

    // qiankun/config.js     // 这里用函数的方式,方便初始化的时候可以设置一些默认参数传进来,例如token等,     // 用于下发给微应用     export const getQiankunConfig = (props = {}) => {       return {         subApps: [           {             name: "xxx-wms", // 子应用名称,建议跟package.json一致             entry: "//192.168.1.40:8990/", // 子应用入口,本地环境下指定端口             container: "#sub-container", // 挂载子应用的dom             activeRule: "/xxx/wms", // 路由匹配规则             props // 主应用与子应用通信传值           },           {             name: "xxx-report", // 子应用名称,跟package.json一致             entry: "//192.168.1.40:9527/#/", // 子应用入口,本地环境下指定端口             container: "#sub-container", // 挂载子应用的dom             activeRule: "/xxx/report", // 路由匹配规则             props // 主应用与子应用通信传值           },         ]       };     };

  • index放初始化函数以及一些其他需要配置和操作
// qiankun/index.js import { registerMicroApps } from "qiankun"; import { getQiankunConfig } from "./configs"; import { getToken } from "@/plugins/cache"; import useUserStore from "@/store/modules/user";  // 设置初始需要传递的值 export const getState = () => {   const { userInfo } = useUserStore();   const state = {     token: getToken(),     accessUser: {       loginName: userInfo.userName || "",       realName: userInfo.userDisplayName || ""     }   };   return state; };  const { subApps } = getConfig(getState()); // 暴露注册函数,里面对应存放生命周期的钩子,可以做需要的处理 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);   } }

新增容器,以及在路由表上增加对应路径的配置

官方原话:当微应用信息注册完之后,一旦浏览器的url发生变化,便会自动触发qiankun的匹配逻辑,所有activeRule规则匹配上的微应用就会被插入到指定的container中,同时依次调用微应用暴露出的生命周期钩子。

  1. 新建subContainer组件,代码如下:
// subContainer.vue <template>  <div id="sub-container"></div> </template>  <script setup> import { start } from "qiankun"; import { registerApps } from "@/qiankun";  onMounted(()=>{    if (!window.qiankunStarted) {      window.qiankunStarted = true;      registerApps();      start({        prefetch: false, // 是否开启预加载, 默认为 true        // sandbox: {        // strictStyleIsolation: true    // 开启严格的样式隔离模式        //   experimentalStyleIsolation: true // 样式隔离        // }      });    } }) </script> 

  1. 路由表配置如下:
// router/xxx.js export const routes = [    // ...    {        // history模式需要通配所有路由,        // 注意:此处xxx需要匹配上面的微前端配置里的activeRule字段        path: "/xxx/:pathMatch(.*)*",        name: "xxxxx",        meta: {},        component: () => import("@/views/subContainer")    }, ]

微应用

  • vue3 + vite,路由模式为history

  • 新建qiankun相关配置文件

    1. 安装vite-plugin-qiankun插件(qiankun目前没有支持vite的文档)

    npm i vite-plugin-qiankun -D

    1. vite.config.js中配置插件

    // vite.config.js     import qiankun from "vite-plugin-qiankun";      export default defineConfig() => {         const { VITE_POWERED_BY_QIANKUN, VITE_PUBLIC_PATH } = env;         return {             base: VITE_PUBLIC_PATH,    // 绝对路径,线上会有跨域问题             plugins: [                 // VITE_POWERED_BY_QIANKUN qiankun的路径前缀                 qiankun(VITE_POWERED_BY_QIANKUN, {                   useDevMode: true                 })             ]         }     }

  1. 导出对应的生命周期钩子,以及初始化方式
   // qiankun.js    import { renderWithQiankun, qiankunWindow } from "vite-plugin-qiankun/dist/helper";     export const render = (app, container) => {      app.mount(container ? container.querySelector("#app") : "#app");    };    export const initQianKun = (app) => {      renderWithQiankun({        mount(props) {          const { container } = props;          render(app, container);        },        bootstrap() {          console.log("bootstrap");        },        unmount() {          app.unmount();        }      });    };    // 初始化,判断是否在子应用的环境中    export const init = (app) => {      qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun(app) : render(app);    };

  • 路由设置,如果是qiankun子应用的环境,增加对应的前缀
    // router/index.js     import { createWebHistory, createRouter } from "vue-router";     const VITE_POWERED_BY_QIANKUN = import.meta.env.VITE_POWERED_BY_QIANKUN;     const router = createRouter({     history: createWebHistory(     qiankunWindow.__POWERED_BY_QIANKUN__       ? `/xxx/${VITE_POWERED_BY_QIANKUN}/`       : "/"     ),     routes: constantRoutes,     scrollBehavior(to, from, savedPosition) {     if (savedPosition) {       return savedPosition;     }     return { top: 0 };     }     });      export default router;

  • 初始化应用
    // main.js     import { createApp } from "vue";     import { init } from "@/qiankun.js";     import App from "./App";     if (window.__POWERED_BY_QIANKUN__) {       // eslint-disable-next-line no-undef       __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;     }     const app = createApp(App);     init(app);

vue2 + webpack ,路由模式为 hash

  • 新建qiankun相关配置文件

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

  1. 导出对应的生命周期钩子,以及初始化方式
    // qiankun.js     import App from './App'     import router from './router'     import store from './store'     import { setToken, setAccessUser, } from "@/utils/auth";      let instance = null     export function render(props = {}) {       const { container } = props       instance = new Vue({         router,         store,         render: h => h(App)       }).$mount(container ? container.querySelector('#app') : '#app')     }      export async function bootstrap(props) {       console.log('[vue] vue app bootstraped', props)     }     export async function mount(props, ...args) {       console.log('[vue] props from main framework', props, args);       setData(props)       props.onGlobalStateChange((state, prev) => {         // state: 变更后的状态; prev 变更前的状态         console.log("🚀 ~ props.onGlobalStateChange ~ state:", state)         setData(state)       });       render(props)     }     export async function unmount() {       instance.$destroy()       instance.$el.innerHTML = ''       instance = null     }     // 拿到主应用传过来的数据进行处理     function setData(state){       if(state['token']){         setToken(state.token)       }       if(state['accessUser']) {         setAccessUser(state.accessUser)       }     }      export default render

  • 路由配置

   // router/index.js    import Router from 'vue-router'    export const constantRouterMap = [ ... ]    export default new Router({      scrollBehavior: () => ({ y: 0 }),      base: window.__POWERED_BY_QIANKUN__ ? '/xxx/report/' : '/',      routes: constantRouterMap    })

  • 初始化应用
  import render from "./qiankun";   // 导出所有的钩子   export * from "./qiankun";   if (window.__POWERED_BY_QIANKUN__) {     __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;   }else {   // 独立运行时     render();   }

总结

  1. 部署上线需要注意资源路径的问题
  2. 不同服务器下的项目需要处理跨域问题
  3. qiankun还有手动加载微应用的方式,暂时还没有用到,可查看官方文档

本文转载于:https://juejin.cn/post/7395387245313163327

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--微前端qiankun接入vue2&vue3项目