vue3+ts+MicroApp實戰(zhàn)教程
項目準備
1、基于amin-work-x項目作為原始項目,改造動態(tài)菜單為自定義菜單


2、分別在主應用項目(main)和子應用(childrenOne,childrenTwo)項目中安裝microApp
npm i @micro-zoe/micro-app --save
子項目配置
1,修改子項目mian.ts,添加與基座的交互配置和路由沖突解決
import { createApp } from "vue";
import App from "./App.vue";
import { Router } from 'vue-router'
import router from "./router";
import "./utils/router";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import "dayjs/locale/zh-cn";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import "@/icons/iconfont/iconfont.css";
import "@/icons/iconfont/iconfont.js";
import "@/styles/main.css";
import LayoutStore from "@/layouts";
import http from "@/api/http";
import { registerComponents } from "./components";
import * as Icons from "@element-plus/icons";
import pinia from "./store/pinia";
import "./setting";
declare global {
interface Window {
microApp: any
__MICRO_APP_NAME__: string
__MICRO_APP_ENVIRONMENT__: string
__MICRO_APP_BASE_ROUTE__: string
}
}
// 與基座進行數(shù)據(jù)交互
function handleMicroData(router: Router) {
// 是否是微前端環(huán)境
if (window.__MICRO_APP_ENVIRONMENT__) {
// 監(jiān)聽基座下發(fā)的數(shù)據(jù)變化
window.microApp.addDataListener((data: Record<string, unknown>) => {
console.log('child-vue3 addDataListener:', data)
// 當基座下發(fā)path時進行跳轉
if (data.path && data.path !== router.currentRoute.value.path) {
router.push(data.path as string)
}
})
// 向基座發(fā)送數(shù)據(jù)
setTimeout(() => {
window.microApp.dispatch({ myname: 'tenant-app' })
}, 3000)
}
}
/**
* 用于解決主應用和子應用都是vue-router4時相互沖突,導致點擊瀏覽器返回按鈕,路由錯誤的問題。
* 相關issue:https://github.com/micro-zoe/micro-app/issues/155
* 當前vue-router版本:4.0.12
*/
function fixBugForVueRouter4(router: Router) {
// 判斷主應用是main-vue3或main-vite,因為這這兩個主應用是 vue-router4
if (window.__MICRO_APP_ENVIRONMENT__) {
//if (window.location.href.includes('/main-vue3') || window.location.href.includes('/main-vite')) {
/**
* 重要說明:
* 1、這里主應用下發(fā)的基礎路由為:`/main-xxx/app-vue3`,其中 `/main-xxx` 是主應用的基礎路由,需要去掉,我們只取`/app-vue3`,不同項目根據(jù)實際情況調整
*
* 2、realBaseRoute 的值為 `/app-vue3`
*/
const realBaseRoute = window.__MICRO_APP_BASE_ROUTE__;//.replace(/^\/app-tenant-[^/]+/g, '')
router.beforeEach(() => {
if (typeof window.history.state?.current === 'string') {
window.history.state.current = window.history.state.current.replace(new RegExp(realBaseRoute, 'g'), '')
}
})
router.afterEach(() => {
if (typeof window.history.state === 'object') {
window.history.state.current = realBaseRoute + (window.history.state.current || '')
}
})
}
}
const app = createApp(App);
Object.keys(Icons).forEach((it) => {
app.component(it, (Icons as any)[it]);
});
registerComponents(app);
app.use(LayoutStore, {
state: {
layoutMode: "ltr",
},
actions: {
onPersonalCenter() {
router.push({ path: "/personal", query: { uid: 1 } });
},
onLogout() {
router.replace({ path: "/login", query: { redirect: "/" } }).then(() => {
window.location.reload();
});
},
},
});
app.use(pinia).use(router);
app.use(ElementPlus, {
locale: zhCn,
});
app.use(http);
app.mount("#app");
handleMicroData(router)
fixBugForVueRouter4(router)
// 監(jiān)聽卸載操作
window.addEventListener('unmount', function () {
//console.log("r4開始卸載", window.location, window.history, app)
app?.unmount()
//console.log('微應用child-vue3卸載了')
})2,修改vue.config.js文件,配置publicPath、端口號、允許跨域

3,為保證子應用的路由在主應用中能直接使用,可在每個路由前添加子應用的路由標志

這一步可不操作,如果不添加,則需要在主應用添加菜單或者動態(tài)獲取菜單時,根據(jù)其他標志,為路由手動加上當前子應用的標志,用于判斷子應用來源
4、修改子應用路由問history模式
const router = createRouter({
history: createWebHistory(window.__MICRO_APP_BASE_ROUTE__||process.env.BASE_URL),
routes: mapTwoLevelRouter([...constantRoutes, ...asyncRoutes]),
});主應用項目配置
1,在layout中添加子應用入口文件(src\layouts\microapp\app-one.vue)
<template>
<div style="height: 100%">
<micro-app
name="appname-one"
:url="url"
baseroute="/app-main"
:data="microAppData"
@created="handleCreate"
@beforemount="handleBeforeMount"
@mounted="handleMount"
@unmount="handleUnmount"
@error="handleError"
@datachange="handleDataChange"
style="height: 100%"
></micro-app>
</div>
</template>
<script lang="ts">
export default {
name: "name-app",
data() {
return {
url:
process.env.NODE_ENV === "development"
? "http://localhost:4009/app-one"
: "通過配置獲取線上地址",
microAppData: { msg: "來自基座的數(shù)據(jù)" },
};
},
methods: {
handleCreate(): void {
console.log("child-vue3 創(chuàng)建了");
},
handleBeforeMount(): void {
console.log("child-vue3 即將被渲染");
},
handleMount(): void {
console.log("child-vue3 已經(jīng)渲染完成");
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.microAppData = { msg: "來自基座的新數(shù)據(jù)" };
}, 2000);
},
handleUnmount(): void {
console.log("child-vue3 卸載了");
},
handleError(): void {
console.log("child-vue3 加載出錯了");
},
handleDataChange(e: CustomEvent): void {
console.log("來自子應用 child-vue3 的數(shù)據(jù):", e.detail.data);
},
},
};
</script>
<style></style>2,在主應用中注冊子應用路由

子應用的路由第一次指向主應用的layout,第二層指向上面新建的入口文件
3,修改主應用publicPath

此處的publicPath需與app-one中的baseroute保持一致
配置完成后,先后運行兩個項目后,在主應用中手動添加一個子應用的的具體頁面路由,就可以在主應用中打開子應用了,但是此時子應用的路由表覆蓋了主應用。
為解決這個問題,需要在子應用中添加一個非layout布局的空頁面,當子應用單獨運行時,指向layout布局頁面,如果是在微服務中使用,則指向空頁面
src\layouts\EmptyLayout.vue
<template>
<div class="empty-layout">
<router-view> </router-view>
</div>
</template>
<style lang="scss" scoped>
.empty-layout {
height: 100%;
}
</style>src\router\index.ts


到此這篇關于vue3+ts+MicroApp實戰(zhàn)教程的文章就介紹到這了,更多相關vue3 ts MicroApp內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解如何從零開始搭建Express+Vue開發(fā)環(huán)境
這篇文章主要介紹了詳解如何從零開始搭建Express+Vue開發(fā)環(huán)境,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
vue awesome swiper異步加載數(shù)據(jù)出現(xiàn)的bug問題
這篇文章主要介紹了vue awesome swiper異步加載數(shù)據(jù)出現(xiàn)的bug問題,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-07-07

