Vue 3 的 实现微前端子应用挂载,关键在于正确导出 bootstrap/mount/unmount 生命周期函数,由主应用动态挂载到指定容器,配合路由 base 配置、样式隔离及 shared 依赖处理。

在 Vue 3 的 <script setup></script> 语法下实现微前端子应用挂载,关键不在于“写法差异”,而在于谁负责挂载、挂载到哪、如何隔离、怎样通信。<script setup></script> 本身是组件内部逻辑组织方式,它不直接参与微前端的加载机制,但会影响子应用自身的导出、生命周期暴露和与主应用的协作方式。
以下是核心要点和实操路径:
子应用侧:用 <script setup></script> 正确导出生命周期钩子
微前端框架(如 qiankun、wujie、micro-app)要求子应用提供 bootstrap、mount、unmount 等标准生命周期函数。Vue 3 + <script setup></script> 默认不暴露这些函数,必须显式导出。
<!-- src/main.ts 或入口文件(非 App.vue) -->
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'
// 创建 router 和 app 实例(注意:不要立即 .mount())
const router = createRouter({ history: createWebHistory(), routes: [...] })
const app = createApp(App)
app.use(router)
// ✅ 必须导出三个函数,供主应用调用
export async function bootstrap() {
console.log('子应用 bootstrap')
}
export async function mount(props) {
// props 是主应用传入的数据(如 container、routerBase、onError 等)
const container = props.container || '#app'
app.mount(container)
}
export async function unmount() {
app.unmount()
}
⚠️ 注意:
- 不要在
main.ts中执行app.mount('#app'),否则会与主应用冲突; -
mount函数中接收props.container,并动态挂载到指定 DOM 节点(这是沙箱隔离和路由接管的前提); - 若使用
createApp(App).mount(),需确保该节点由主应用创建并传入,不能硬编码#app。
主应用侧:通过 或 组件加载子应用
<script setup></script> 对主应用无特殊限制,只需按框架规范使用封装好的微前端组件即可。
将静态 Vue 页面(index.vue)改造为动态页面(Custom.vue);稿源仅限 index.vue、其引用的 CSS 与资源路径,禁止参考仓库内其他文件。Invoke when user wants to transform a static Vue page into a dynamic data-driven page with Element UI components.
以 wujie-vue3 为例(Vue 3 主应用加载 Vue 3 子应用):
<template><div class="subapp-container" ref="containerRef"></div>
<wujievue width="100%" height="100%" :name="appName" :url="appUrl" :props="{ token: userToken }"></wujievue></template><script setup>
import { ref, onMounted } from 'vue'
import WujieVue from 'wujie-vue3'
const appName = 'vue3-subapp'
const appUrl = 'http://localhost:5173/' // 子应用服务地址
const userToken = localStorage.getItem('token')
const containerRef = ref(null)
</script>
以 micro-app 为例(轻量级方案):
<template><micro-app :name="appName" :url="appUrl" :baseroute="baseRoute" :data="{ token: userToken }"></micro-app></template><script setup>
import microApp from '@micro-zoe/micro-app'
import { onMounted } from 'vue'
const appName = 'vue3-subapp'
const appUrl = 'http://localhost:5173/'
const baseRoute = '/subapp'
const userToken = localStorage.getItem('token')
const onMounted = () => {
console.log('子应用已挂载')
}
</script>
关键细节:路由与样式隔离需子应用配合
-
路由模式:子应用若用
history模式,必须配置base,且该base需与主应用分配的路径前缀一致(如主应用路由/subapp/*→ 子应用createWebHistory('/subapp/')); -
样式隔离:
<script setup></script>下推荐用,但微前端框架(如 wujie、qiankun)还会启用 JS 沙箱 + CSS 作用域隔离(如实验性experimentalStyleIsolation),二者互补; -
共享依赖:避免子应用重复打包
vue、vue-router等,应在vite.config.ts中设为external,由主应用统一提供。
子应用通信:父传子用 props,子传父用事件或全局总线
主应用通过 props 向子应用传数据(如用户信息、主题色),子应用可通过以下方式回传:
- 使用
window.dispatchEvent触发自定义事件(需主应用监听); - 或在
mount时接收props.onMessage回调函数,子应用内调用props.onMessage({ type: 'login', data }); - 更规范的做法:子应用内部封装一个
useMicroContext()composable,统一管理跨应用通信。
不复杂但容易忽略
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









