实现将 Vue3 项目作为子应用,通过无界(Wujie)微前端框架接入到 Vue2 主应用中(Vue2 为主应用,Vue3 为子应用)

实现将 Vue3 项目作为子应用,通过无界(Wujie)微前端框架接入到 Vue2 主应用中(Vue2 为主应用,Vue3 为子应用)。无界针对 Vue2 主应用提供了专属适配包wujie-vue2,且 Vue3 子应用无需任何修改(零改造接入)。下面是超级详细的实现步骤:

一、前提准备

  1. Vue2 主应用:已搭建且能独立运行(如基于 Vue CLI 创建,运行在http://localhost:8080);
  2. Vue3 子应用:已搭建且能独立运行(如基于 Vite 创建,运行在http://localhost:5173);
  3. 无界适配包:Vue2 主应用需安装wujie-vue2(无界针对 Vue2 的适配包)。

二、步骤 1:Vue3 子应用准备(零改造)

Vue3 子应用无需修改任何代码,只需保证:

  • 能独立运行(如通过npm run dev启动,默认端口5173);
  • 若使用history路由模式,需配置base路径(避免子应用资源路径错误)。
(可选)Vue3 子应用路由配置(history 模式)

若 Vue3 子应用用history模式,修改src/router/index.js

import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL || '/vue3-app/'), // 生产环境可配置前缀
  routes: [
    { path: '/', name: 'Home', component: Home },
    { path: '/about', name: 'About', component: () => import('@/views/About.vue') }
  ]
});

export default router;

启动 Vue3 子应用:

cd vue3-subapp
npm run dev  # 运行在http://localhost:5173

三、步骤 2:Vue2 主应用集成无界

1. Vue2 主应用安装无界 Vue2 适配包
cd vue2-mainapp
npm install wujie-vue2  # 或cnpm install wujie-vue2(若npm速度慢)
2. Vue2 主应用全局注册无界组件(可选)

在 Vue2 主应用的main.js中全局注册无界组件,方便所有页面使用:

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import WujieVue2 from 'wujie-vue2'; // 引入无界Vue2适配组件

Vue.config.productionTip = false;
Vue.use(WujieVue2); // 全局注册无界组件

new Vue({
  router,
  render: h => h(App)
}).$mount('#app');
3. Vue2 主应用创建 Vue3 子应用容器组件

在 Vue2 主应用中创建专门的页面组件(如src/views/Vue3App.vue),用于承载 Vue3 子应用:

<template>
  <div class="vue3-app-container">
    <h2>Vue2主应用集成Vue3子应用(无界)</h2>
    <!-- 无界微前端容器:接入Vue3子应用 -->
    <WujieVue2
      name="vue3-app"          <!-- 子应用唯一标识(不可重复) -->
      url="http://localhost:5173/"  <!-- Vue3子应用独立访问地址 -->
      width="100%"             <!-- 子应用宽度 -->
      height="600px"           <!-- 子应用高度 -->
      :props="{ token: 'vue2-main-token', user: { name: 'admin' } }"  <!-- 主应用传参 -->
      :sync="true"             <!-- 同步子应用路由到主应用URL(可选) -->
      prefix="/vue3-app"       <!-- 子应用路由前缀(配合sync使用,可选) -->
      @subAppMounted="handleVue3Mounted"  <!-- 监听子应用挂载完成事件 -->
    />
  </div>
</template>

<script>
export default {
  name: 'Vue3App',
  methods: {
    handleVue3Mounted(appWindow) {
      console.log('Vue3子应用挂载完成', appWindow);
      // 调用Vue3子应用暴露的全局方法(若有)
      if (appWindow.vue3AppMethod) {
        appWindow.vue3AppMethod('来自Vue2主应用的调用');
      }
    }
  }
};
</script>

<style scoped>
.vue3-app-container {
  padding: 20px;
}
</style>
4. Vue2 主应用配置路由

在 Vue2 主应用的路由配置中添加 Vue3 子应用的路由(src/router/index.js):

import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/views/Home';
import Vue3App from '@/views/Vue3App'; // 引入Vue3子应用容器组件

Vue.use(Router);

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    { path: '/', name: 'Home', component: Home },
    { path: '/vue3-app', name: 'Vue3App', component: Vue3App } // 新增路由
  ]
});
5. Vue2 主应用添加导航

在 Vue2 主应用的根组件(App.vue)中添加跳转到 Vue3 子应用的导航:

<template>
  <div id="app">
    <nav>
      <router-link to="/">Vue2首页</router-link> |
      <router-link to="/vue3-app">Vue3子应用</router-link>
    </nav>
    <router-view/>
  </div>
</template>

<style scoped>
nav {
  padding: 20px;
  background: #f5f5f5;
  margin-bottom: 20px;
}
nav a {
  margin-right: 10px;
  text-decoration: none;
  color: #409eff;
}
</style>

四、步骤 3:Vue3 子应用与 Vue2 主应用通信(可选)

无界会将 Vue2 主应用传递的props挂载到 Vue3 子应用的window.$wujie.props上,Vue3 子应用可直接读取;也可暴露全局方法供主应用调用。

1. Vue3 子应用读取主应用参数

修改 Vue3 子应用的src/App.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/vue.svg">
    <h1>Vue3子应用</h1>
    
    <!-- 显示主应用传递的参数 -->
    <div v-if="mainProps" style="margin-top: 20px; text-align: left; padding: 0 20px;">
      <p>主应用传递的Token:{{ mainProps.token }}</p>
      <p>用户名:{{ mainProps.user.name }}</p>
    </div>
    
    <button @click="sendMsgToVue2">给Vue2主应用发消息</button>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const mainProps = ref(null);

onMounted(() => {
  // 读取无界挂载的主应用参数
  mainProps.value = window.$wujie?.props;
  
  // 暴露全局方法给Vue2主应用调用
  window.vue3AppMethod = (msg) => {
    alert(`Vue3子应用收到主应用消息:${msg}`);
  };
});

onUnmounted(() => {
  // 组件卸载时清理全局方法
  delete window.vue3AppMethod;
});

// 向Vue2主应用发送消息
const sendMsgToVue2 = () => {
  window.$wujie?.bus.$emit('vue3-to-vue2', { data: 'Hello Vue2主应用!' });
};
</script>
2. Vue2 主应用监听 Vue3 子应用的消息

在 Vue2 主应用的Vue3App.vue中监听无界事件总线:

<script>
import { bus } from 'wujie-vue2'; // 引入无界事件总线

export default {
  name: 'Vue3App',
  created() {
    // 监听Vue3子应用发送的事件
    bus.$on('vue3-to-vue2', (data) => {
      console.log('Vue2主应用收到Vue3子应用消息:', data);
      alert(`Vue2主应用收到:${data.data}`);
    });
  },
  methods: {
    handleVue3Mounted(appWindow) {
      console.log('Vue3子应用挂载完成', appWindow);
      if (appWindow.vue3AppMethod) {
        appWindow.vue3AppMethod('来自Vue2主应用的调用');
      }
    }
  }
};
</script>

五、步骤 4:启动测试

  1. 启动 Vue3 子应用:cd vue3-subapp && npm run dev(运行在http://localhost:5173);
  2. 启动 Vue2 主应用:cd vue2-mainapp && npm run serve(运行在http://localhost:8080);
  3. 访问 Vue2 主应用的/vue3-app路径,即可看到 Vue3 子应用被嵌入到 Vue2 主应用中,且能正常交互、通信。

六、常见问题与解决方案

1. Vue3 子应用资源加载失败(跨域)
  • 原因:浏览器同源策略限制,Vue2 主应用访问 Vue3 子应用的资源时跨域;
  • 解决方案:无界在开发环境会自动代理子应用请求,无需额外配置;生产环境需配置 Nginx 反向代理(见下文)。
2. Vue3 子应用路由刷新 404(history 模式)
  • 原因:子应用history模式下,刷新主应用 URL(如http://localhost:8080/vue3-app/about)时,主应用服务器无法识别子应用路由;

  • 解决方案:

    • 开发环境:Vue2 主应用(Vue CLI)配置devServer.proxy代理子应用路由:

      // Vue2主应用的vue.config.js
      module.exports = {
        devServer: {
          port: 8080,
          proxy: {
            '/vue3-app': {
              target: 'http://localhost:5173',
              changeOrigin: true,
              rewrite: (path) => path.replace(/^\/vue3-app/, '') // 去掉前缀
            }
          }
        }
      };
      
    • 生产环境:配置 Nginx 代理(见下文)。

3. Vue3 子应用样式污染 Vue2 主应用
  • 原因:无界默认通过 Shadow DOM 隔离样式,但 Vue3 子应用的全局样式(如body样式)可能穿透;
  • 解决方案:Vue3 子应用的组件样式添加scoped,或主应用通过:global()覆盖全局样式。

七、生产环境部署配置(Nginx)

生产环境需配置 Nginx 反向代理,解决跨域和路由问题:

server {
  listen 80;
  server_name your-domain.com;

  # Vue2主应用
  location / {
    root /path/to/vue2-mainapp/dist;
    index index.html;
    try_files $uri $uri/ /index.html; # 处理Vue2主应用history路由
  }

  # Vue3子应用代理(配合无界的prefix="/vue3-app")
  location /vue3-app/ {
    proxy_pass http://localhost:5173/; # Vue3子应用的生产地址
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    try_files $uri $uri/ /index.html; # 处理Vue3子应用history路由
  }
}

总结

  1. 核心逻辑:Vue2 主应用安装wujie-vue2,通过<WujieVue2>组件配置 Vue3 子应用的nameurl即可接入,Vue3 子应用零改造;
  2. 通信方式:主应用通过props传参,子应用通过window.$wujie.props接收;通过无界事件总线bus实现双向通信;
  3. 关键配置:生产环境需配置 Nginx 代理解决跨域和路由刷新问题,history模式需配合prefixsync实现路由同步。

通过无界,你可以轻松实现 Vue2 主应用集成 Vue3 子应用,甚至同时集成 React、jQuery 等其他技术栈的子应用,实现真正的技术栈无关微前端架构。

### 3.1 主应用配置子应用加载组件主应用中,使用 `WujieVue` 组件来加载子应用,并通过菜单项触发路由跳转。在 Vue3 + Vite 的项目结构下,首先需要引入 `wujie-vue3` 模块,并将其挂载到 Vue 应用中。 ```ts // main.ts import { createApp } from &#39;vue&#39; import WujieVue from &#39;wujie-vue3&#39; import App from &#39;./App.vue&#39; const app = createApp(App) app.use(WujieVue).mount(&#39;#app&#39;) ``` 接着,在主应用的菜单组件中配置路由跳转功能,例如使用 `el-menu-item` 设置菜单项并绑定子应用路径: ```vue <template> <el-menu mode="inline" router> <el-menu-item index="/platformManagement"> <span>平台管理</span> </el-menu-item> </el-menu> </template> ``` ### 3.2 子应用页面显示与动态路由处理 为了实现点击菜单后加载对应的子应用页面,可以在主应用中创建一个用于承载子应用内容的组件,并监听 `$route.params.path` 的变化,从而动态更新子应用的 URL。 ```vue <template> <div class="subapp-container"> <WujieVue width="100%" height="100%" name="react17" :url="react17Url" /> </div> </template> <script> import hostMap from "../../wujie-config/hostMap" export default { data() { return { react17Url: &#39;&#39; } }, watch: { "$route.params.path": { handler: function () { this.react17Url = hostMap("//localhost:7100/") + `/${this.$route.params.path}` // 若启用保活模式,则需通过通信方式通知子应用路由变化 window.wujie?.bus.$emit("react17-router-change", `/${this.$route.params.path}`) }, immediate: true } } } </script> ``` ### 3.3 子应用通信机制配置 若需在子应用间传递数据或进行事件广播,可以通过 `window.parent.postMessage` 实现应用通信。主应用可监听来自子应用的消息,并作出相应处理。 ```js // 主应用监听子应用消息 window.addEventListener(&#39;message&#39;, (event) => { if (event.data.from === &#39;wujie&#39;) { console.log(&#39;收到子应用消息:&#39;, event.data.payload) } }) ``` 而在子应用中发送消息至主应用的方式如下: ```js // 子应用主应用发送消息 window.parent.postMessage({ from: &#39;wujie&#39;, payload: &#39;Hello 主应用!&#39; }, &#39;*&#39;) ``` ### 3.4 性能优化与开发调试建议 - **懒加载策略**:仅在用户访问对应功能时加载子应用资源,减少首屏加载时间。 - **沙箱行为控制**:根据实际需求合理配置沙箱行为,避免不必要的性能损耗。 - **浏览器缓存利用**:开启浏览器缓存机制,提升子应用二次加载速度。 - **本地代理调试**:使用本地开发服务器代理子应用资源,确保跨域问题可控。 - **启用 Debug 模式**:在 Wujie 初始化时启用 debug 模式,输出详细的运行日志以辅助调试[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涔溪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值