实现将 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

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 子应用:

bash 复制代码
cd vue3-subapp
npm run dev  # 运行在http://localhost:5173

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

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

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

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 子应用:

vue 复制代码
<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):

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 子应用的导航:

vue 复制代码
<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

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中监听无界事件总线:

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代理子应用路由:

      js 复制代码
      // 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 反向代理,解决跨域和路由问题:

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 等其他技术栈的子应用,实现真正的技术栈无关微前端架构。

相关推荐
4***14901 小时前
TypeScript在React中的前端框架
react.js·typescript·前端框架
S***42801 小时前
Web3.0在去中心化应用中的前端框架
前端框架·web3·去中心化
源码技术栈3 小时前
什么是云门诊系统、云诊所系统?
java·vue.js·spring boot·源码·门诊·云门诊
lcc1873 小时前
Vue3 ref函数和reactive函数
前端·vue.js
艾小码3 小时前
还在为组件通信头疼?defineExpose让你彻底告别传值烦恼
前端·javascript·vue.js
带只拖鞋去流浪3 小时前
迎接2026,重新认识Vue CLI (v5.x)
前端·vue.js·webpack
Coder-coco3 小时前
游戏助手|游戏攻略|基于SprinBoot+vue的游戏攻略系统小程序(源码+数据库+文档)
java·vue.js·spring boot·游戏·小程序·论文·游戏助手
c***V3236 小时前
Vue优化
前端·javascript·vue.js
zy happy11 小时前
若依 vue3 报错:找不到模块“@/api/xxxx/xxxxx”或其相应的类型声明。。Vue 3 can not find mod
前端·javascript·vue.js