Vue3+vue-cli+qiankun+hash路由

[寫(xiě)在前面]

...等等再寫(xiě)...

[需要什么]
主應(yīng)用:

  1. 加載子服務(wù)的容器(不一定在 public/index.html 文件中,可以是任意位置),給一個(gè)id
  2. 加載子服務(wù)的路由,配置router,準(zhǔn)備一個(gè)空頁(yè)面占位
  3. 在 src.main.js 中,注冊(cè)子路由,啟動(dòng)qiankun
  4. 本地啟動(dòng)的話,是否需要代理接口,proxy自己配一下

子應(yīng)用:

  1. 子服務(wù)的入口容器,id最好與主應(yīng)用的容器id 區(qū)分開(kāi),使用不同的命名
  2. 在 src.main.js 中,導(dǎo)出qiankun需要的生命周期
  3. 新增 src/public-path.js ,進(jìn)行配置
  4. 路由改造,使用與主應(yīng)用相同的路由路徑,防止無(wú)法找到頁(yè)面
  5. 在 vue.config.js 中,進(jìn)行改造

[開(kāi)始之前]
先使用vue3 + vue-cli 創(chuàng)建兩個(gè)項(xiàng)目
主應(yīng)用和子應(yīng)用 最好使用同一版本的組件庫(kù),不然可能報(bào)錯(cuò),或產(chǎn)生樣式問(wèn)題

[開(kāi)始啦]
安裝qiankun,我這里安裝的是qiankun@2.10.16

主應(yīng)用:

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

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

export default route


// @/views/empty.vue 空白頁(yè)面
<template>
  <div style="background: tansparent"></div>
</template>

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

<style lang="less" scoped></style>
  1. 子應(yīng)用容器
  <div id="sub-container"></div>       
  1. 注冊(cè)子應(yīng)用
// src/main.ts

import { registerMicroApps, start, prefetchApps } from "qiankun"
// 匹配路由路徑
const getActiveRule = (hash) => (location) => {
  return location.hash.startsWith(hash)
}
// 注冊(cè)子應(yīng)用
registerMicroApps(
  [
    {
      name: "subApp",
      entry: "http://localhost:8081", // 發(fā)布上線后,換成該路徑地址
      container: "#sub-container",
      activeRule: getActiveRule("#/djTrans/projectCollection"), // "/#/djTrans/transTool",
      props: {
        msg: "我是來(lái)自主應(yīng)用的值-vue", // 主應(yīng)用向微應(yīng)用傳遞參數(shù)
      },
    },
  ]
)

// 啟動(dòng) 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)
        },
      },

子應(yīng)用:

  1. 導(dǎo)出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();
}

// 子組件暴露三個(gè)函數(shù)
export async function bootstrap(props) {
  console.log('我是bootstrap項(xiàng)目函數(shù)', props);
}
export async function mount(props) {
  console.log('我是mount項(xiàng)目函數(shù)', props);
  render(props);
}
export async function unmount(props) {
  console.log('我是vue項(xiàng)目unmount函數(shù)', props);
  history = null;
  app = null;
  router = null;
}
  1. 新增 src/public-path.js ,進(jìn)行配置
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/'; // 填寫(xiě)你的實(shí)際部署地址

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

module.exports = defineConfig({
  // 打開(kāi)文件訪問(wèn)的相對(duì)路徑 獨(dú)立項(xiàng)目 通過(guò)項(xiàng)目根目錄訪問(wèn)
  publicPath: 'http://localhost:8081', // '/' // 部署上線后,換成子應(yīng)用打開(kāi)的路徑
  // transpileDependencies: true, // 轉(zhuǎn)義依賴(lài)項(xiàng)
  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官網(wǎng):https://qiankun.umijs.org/zh/guide
webpack官網(wǎng):https://www.webpackjs.com/
qiankun引入vue3子項(xiàng)目實(shí)踐:https://zhuanlan.zhihu.com/p/618433202
簡(jiǎn)書(shū)例子:http://www.itdecent.cn/p/b8599fddc6bb
vue使用qiankun框架心得和踩坑記錄:https://blog.csdn.net/weixin_40883720/article/details/122358162
qiankun報(bào)錯(cuò):
https://blog.csdn.net/m0_67401382/article/details/123426513
https://blog.csdn.net/haoran87/article/details/136660839

遇到的問(wèn)題

image.png

[報(bào)錯(cuò)]qiankun報(bào)錯(cuò):Maximum call stack size exceeded
[我的解決] 主應(yīng)用啟動(dòng)乾坤時(shí),給參數(shù)start({ sandbox: false })

image.png

[報(bào)錯(cuò)]qiankun報(bào)錯(cuò):You need to export lifecycle functions in djTrans entry
[我的解決] 子應(yīng)用output配置有問(wèn)題,主應(yīng)用沒(méi)有找到子應(yīng)用

[報(bào)錯(cuò)]qiankun報(bào)錯(cuò):[qiankun] prefetch starting after vueApp mounted...
[報(bào)錯(cuò)]qiankun報(bào)錯(cuò):[qiankun:sandbox] vueApp modified global properties
[報(bào)錯(cuò)]qiankun報(bào)錯(cuò):[qiankun]: Wrapper element for djtranstool is not existed!restore...
[我的解決] 這報(bào)錯(cuò),我忘了怎么解決的了,先記上,證明我遇見(jiàn)過(guò),并解決了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容