vue实现微前端
Vue 实现微前端的方案
Vue 实现微前端主要有以下几种方案,每种方案适用于不同的场景和需求。
使用 qiankun 框架
qiankun 是一个基于 single-spa 的微前端解决方案,支持 Vue 应用作为主应用或子应用。
主应用配置
在主应用中注册子应用,通常在主应用的入口文件(如 main.js)中配置:
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'vue-sub-app',
entry: '//localhost:7101',
container: '#subapp-container',
activeRule: '/vue-sub-app',
},
]);
start();
子应用配置 子应用需要导出生命周期钩子函数,并在入口文件中适配:
import Vue from 'vue';
import App from './App.vue';
let instance = null;
function render(props = {}) {
const { container } = props;
instance = new Vue({
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('vue sub app bootstraped');
}
export async function mount(props) {
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
使用 single-spa 原生方案
single-spa 是一个更底层的微前端框架,需要手动配置路由和生命周期。
主应用配置 在主应用中注册子应用:
import { registerApplication, start } from 'single-spa';
registerApplication({
name: 'vue-sub-app',
app: () => System.import('vue-sub-app'),
activeWhen: '/vue-sub-app',
});
start();
子应用配置 子应用需要导出生命周期函数:
import Vue from 'vue';
import App from './App.vue';
import router from './router';
const vueLifecycles = {
bootstrap: async () => {
console.log('vue app bootstrap');
},
mount: async (props) => {
const instance = new Vue({
router,
render: h => h(App),
}).$mount(props.domElementId);
},
unmount: async (props) => {
instance.$destroy();
},
};
export default vueLifecycles;
使用 Module Federation(Webpack 5)
Webpack 5 的 Module Federation 功能可以实现微前端,适用于现代前端架构。
主应用配置
在主应用的 webpack.config.js 中配置:
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
vueSubApp: 'vueSubApp@http://localhost:3001/remoteEntry.js',
},
}),
],
};
子应用配置
在子应用的 webpack.config.js 中配置:
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'vueSubApp',
filename: 'remoteEntry.js',
exposes: {
'./App': './src/App.vue',
},
}),
],
};
使用 iframe 嵌入
iframe 是一种简单的微前端实现方式,但隔离性较强,通信较复杂。
主应用中使用 iframe
在主应用的 Vue 组件中嵌入子应用:
<template>
<iframe src="http://localhost:7101" frameborder="0"></iframe>
</template>
子应用适配
子应用无需特殊配置,但需要注意跨域问题和通信机制(如 postMessage)。
通信机制
微前端中主应用和子应用之间的通信可以通过以下方式实现:
- 全局状态管理:使用
Vuex或Pinia共享状态。 - 自定义事件:通过
window.dispatchEvent和window.addEventListener实现跨应用通信。 qiankun提供的通信工具:使用initGlobalState方法:
// 主应用中初始化全局状态
import { initGlobalState } from 'qiankun';
const actions = initGlobalState(state);
actions.onGlobalStateChange((state, prev) => {
console.log('主应用监听状态变化', state, prev);
});
actions.setGlobalState({ ...state, ignore: '初始状态' });
// 子应用中获取全局状态
export function mount(props) {
props.onGlobalStateChange((state, prev) => {
console.log('子应用监听状态变化', state, prev);
});
props.setGlobalState({ ...state, ignore: '子应用状态' });
}
样式隔离
微前端中的样式隔离可以通过以下方式实现:
- Shadow DOM:使用 Shadow DOM 隔离子应用样式。
- CSS 命名空间:为子应用的样式添加唯一前缀。
- 动态样式表:在子应用加载时动态添加样式,卸载时移除。
部署注意事项
- 子应用独立部署:子应用应支持独立运行和作为微应用嵌入。
- 路由兼容:主应用和子应用的路由应避免冲突,通常使用路由前缀区分。
- 资源路径处理:子应用的静态资源路径可能需要调整为绝对路径。
以上方案可根据实际需求选择,qiankun 和 Module Federation 是目前较为流行的方案。







