背景部分,公司后端采用 Spring Cloud 微服务架构,订单、商品、报价等模块独立打包部署,有效降低了业务耦合。近期项目重构,领导要求前端也尝试微服务模式,实现各模块单独编译与部署。任务压下来后,我开始调研前端分布式方案。
起初考虑用 Webpack 进行分包编译,但研究配置文档后发现复杂度较高。权衡之后,决定调整方向:将每个模块单独编译成包,通过 iframe 嵌套到基础框架中。虽然 iframe 方案存在通信和样式隔离等缺点,但在当前阶段,这是实现物理隔离最可行的路径。
实施过程中,主要需要解决四个核心问题:
- 外部路由如何定位内部内容
- 组件资源依赖与版本管理
- 域名部署及 iframe 操作封装
- 跨应用、跨 iframe 的状态管理
下面逐一拆解解决方案。
路由配置
在 router.js 中定义一个用于承载 iframe 的容器组件,利用通配符捕获子路由:
{
path: '/iframe',
name: 'iframe',
component: () => import(/* webpackChunkName: "about" */ './views/Iframe.vue'),
children: [
{
path: '*',
component: () => import('./views/OtherMain.vue'),
name: '加载外部的内容'
}
]
}
这里使用 * 匹配所有子路径,确保动态跳转时能正确加载目标页面。
Iframe 组件实现
OtherMain.vue 负责根据路由参数动态切换 iframe 地址。核心逻辑在于监听路由变化并映射到对应的模块 URL:
<template>
<div class="about">
<h1>{{ url }}</h1>
<iframe :src="url"></iframe>
</div>
</template>
<script>
export default {
name: 'OtherMain',
data() {
return {
url: ''
}
},
mounted() {
let newPath = this.$router.currentRoute.fullPath
this.url = this.changeUrl(newPath)
},
methods: {
changeUrl(newPath) {
let returnUrl = ''
// 实际项目中建议配置化或从环境变量读取
if (newPath === '/iframe/product/list') {
returnUrl = 'https://module-a.example.com/home/book.html'
} else if (newPath === '/iframe/order/list') {
returnUrl = 'https://module-a.example.com/home/drew.html'
}
return returnUrl
},
},
beforeRouteUpdate(to, from, next) {
let newPath = to.path
this.url = this.changeUrl(newPath)
next()
}
}
</script>
changeUrl 方法可以提取为独立的工具函数,作为路径匹配资源的转换器。大致的思路就是这样:利用正则路由配合路由守卫,监听组件内 url 的改变,从而驱动 iframe 加载不同的外部内容。

