Vue3+vue-cli+qiankun+hash路由

[写在前面]

...等等再写...

[需要什么]
主应用:

  1. 加载子服务的容器(不一定在 public/index.html 文件中,可以是任意位置),给一个id
  2. 加载子服务的路由,配置router,准备一个空页面占位
  3. 在 src.main.js 中,注册子路由,启动qiankun
  4. 本地启动的话,是否需要代理接口,proxy自己配一下

子应用:

  1. 子服务的入口容器,id最好与主应用的容器id 区分开,使用不同的命名
  2. 在 src.main.js 中,导出qiankun需要的生命周期
  3. 新增 src/public-path.js ,进行配置
  4. 路由改造,使用与主应用相同的路由路径,防止无法找到页面
  5. 在 vue.config.js 中,进行改造

[开始之前]
先使用vue3 + vue-cli 创建两个项目
主应用和子应用 最好使用同一版本的组件库,不然可能报错,或产生样式问题

[开始啦]
安装qiankun,我这里安装的是qiankun@2.10.16

主应用:

  1. 增加路由配置
import { RouteRecordRaw } from "vue-router"

export const route: RouteRecordRaw = {
  path: "subView",
  name: "子应用",
  meta: { title: "子应用", icon: "mes-user" },
  redirect: "/subView",
  children: [
    {
      path: "subView1",
      name: "子应用菜单",
      component: () => import("@/views/empty.vue"),
      meta: { title: "子应用"},
      children: [
        {
          path: ":w",
          component: () => import("@/views/empty.vue"),
        },
      ],
    },
  ],
}

export default route


// @/views/empty.vue 空白页面
<template>
  <div style="background: tansparent"></div>
</template>

<script setup lang="ts"></script>

<style lang="less" scoped></style>
  1. 子应用容器
  <div id="sub-container"></div>       
  1. 注册子应用
// src/main.ts

import { registerMicroApps, start, prefetchApps } from "qiankun"
// 匹配路由路径
const getActiveRule = (hash) => (location) => {
  return location.hash.startsWith(hash)
}
// 注册子应用
registerMicroApps(
  [
    {
      name: "subApp",
      entry: "http://localhost:8081", // 发布上线后,换成该路径地址
      container: "#sub-container",
      activeRule: getActiveRule("#/djTrans/projectCollection"), // "/#/djTrans/transTool",
      props: {
        msg: "我是来自主应用的值-vue", // 主应用向微应用传递参数
      },
    },
  ]
)

// 启动 qiankun
start({ sandbox: false }) // 沙箱,防止样式影响
  1. 代理自己配一下
"/subView": {
        target: proxy3,
        changeOrigin: true,
        onProxyReq(proxyReq, req, res) {
          originHost = req.headers["x-forwarded-for"]
          proxyReq.setHeader("Cookie", "token=" + process.env.VUE_SERVER_TOKEN)
        },
      },

子应用:

  1. 导出qiankun需要的生命周期
// src/main.ts
import store from './store';
import antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';
import '@/assets/global.less';

import { createApp } from 'vue';
import 'qiankun';
import { createRouter, createWebHistory } from 'vue-router';
import App from './App.vue';
import routes from './router';

let app;
let router;
let history;
function render(props = { container: undefined }) {
  history = createWebHistory(process.env.BASE_URL);
  router = routes;
  app = createApp(App);
  app.use(antd);
  app.use(store);
  const { container } = props;
  app.use(router).mount(container ? container.querySelector('#sub-app') : '#sub-app');
}

if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

// 子组件暴露三个函数
export async function bootstrap(props) {
  console.log('我是bootstrap项目函数', props);
}
export async function mount(props) {
  console.log('我是mount项目函数', props);
  render(props);
}
export async function unmount(props) {
  console.log('我是vue项目unmount函数', props);
  history = null;
  app = null;
  router = null;
}
  1. 新增 src/public-path.js ,进行配置
if (window.__POWERED_BY_QIANKUN__) {
  // __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
  __webpack_require__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

__webpack_public_path__ = window.__POWERED_BY_QIANKUN__
  ? window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
  : 'http://111.11.51.41:8081/'; // 填写你的实际部署地址

  1. 按照主应用的路由,修改子应用路由
const router = createRouter({
  history: createWebHashHistory(process.env.BASE_URL),
  routes
});
  1. 修改配置
// vue.config.js
const { name } = require('./package');

module.exports = defineConfig({
  // 打开文件访问的相对路径 独立项目 通过项目根目录访问
  publicPath: 'http://localhost:8081', // '/' // 部署上线后,换成子应用打开的路径
  // transpileDependencies: true, // 转义依赖项
  productionSourceMap: false,
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      // library: 'vueApp',
      libraryTarget: 'umd',
      chunkLoadingGlobal: `webpackJsonp_${name}` // jsonpFunction
    }
  },
  devServer: {
    open: false,
    port: 8081,
    host: 'localhost',
    https: false,
    proxy: {
      '/': {
        target: proxy3,
        ws: false,
        changeOrigin: true,
      }
    },
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': '*'
    }
  }
});

参考文档

qiankun官网:https://qiankun.umijs.org/zh/guide
webpack官网:https://www.webpackjs.com/
qiankun引入vue3子项目实践:https://zhuanlan.zhihu.com/p/618433202
简书例子://www.greatytc.com/p/b8599fddc6bb
vue使用qiankun框架心得和踩坑记录:https://blog.csdn.net/weixin_40883720/article/details/122358162
qiankun报错:
https://blog.csdn.net/m0_67401382/article/details/123426513
https://blog.csdn.net/haoran87/article/details/136660839

遇到的问题

image.png

[报错]qiankun报错:Maximum call stack size exceeded
[我的解决] 主应用启动乾坤时,给参数start({ sandbox: false })

image.png

[报错]qiankun报错:You need to export lifecycle functions in djTrans entry
[我的解决] 子应用output配置有问题,主应用没有找到子应用

[报错]qiankun报错:[qiankun] prefetch starting after vueApp mounted...
[报错]qiankun报错:[qiankun:sandbox] vueApp modified global properties
[报错]qiankun报错:[qiankun]: Wrapper element for djtranstool is not existed!restore...
[我的解决] 这报错,我忘了怎么解决的了,先记上,证明我遇见过,并解决了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。