这两天 公司往后有个新项目 是这么这么个需求:

主项目 需要能引入各种项目整合 于是了解到了微前端

第一天先是深入挖掘 qiankun 这个框架 玩了一天结果无法满足我们公司的一些场景 果断放弃

第二天了解到了 京东的全新框架

图片转自官网

图片转自官网

但是很不幸 子项目的路由比较复杂 我们的需求是 主项目的某个区域 直接加载子项目的某个vue 组件显示
就好比直接在vue项目中 components创建了一个 组件 然后在App.vue 引入这样

于是研究了半天 对子项目进行了改造 (后面会说具体实现!!!)
最终效果如下:
2024-08-05T05:55:31.png

2024-08-05T05:55:31.png

先看下原理图(左部分)

2024-08-05T05:55:41.png

2024-08-05T05:55:41.png

在附上一张子项目打包后的文件

2024-08-05T05:55:50.png

2024-08-05T05:55:50.png

将每个入口通过nginx 代理web请求

只需要在通过microApp 标签正常定义即可

2024-08-05T05:55:52.png

2024-08-05T05:55:52.png

接下来开始说具体实现:

首先创建两个项目
  • micro-main (主项目)
  • micro-children (子项目)

(这边直接省略创建项目的过程 使用的是vue 脚手架 最新的vue2)

micro-main

主应用需要安装依赖

npm i @micro-zoe/micro-app --save

创建完后初始化micro-app 编辑main.js

2024-08-05T05:56:23.png

2024-08-05T05:56:23.png

贴身代码 方便复制

// =============引入micro依赖============== import microApp from '@micro-zoe/micro-app' microApp.start() Vue.config.productionTip = false const app =new Vue({ router, render: h => h(App) }).$mount('#app') // 卸载应用 window.unmount = () => { app.$destroy() } // ==========================================

然后在编辑 vue.config.js

2024-08-05T05:56:33.png

2024-08-05T05:56:33.png

加上 这两行 (当然这个不是重点 主要是为了解决打包后页面空白的问题)

publicPath: './', assetsDir: 'static'
ok 主应用就这样 接下来 打开子应用项目

micro-children

先看下子项目改造后的结构

2024-08-05T05:56:40.png

2024-08-05T05:56:40.png

第一步 比如我需要两个子组件

  • 侧边栏
  • 顶部栏
    然后分别写这两个组件 放在 components文件夹 如上图

第二步

复制main.js 并命名为 header.js sidebar.js

废话不多说
我这边贴上我的代码

/*header.js 顶部栏*/ import Vue from 'vue' // 引入刚才的顶部栏组件 import App from '@/components/Header.vue' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); Vue.config.productionTip = false const app =new Vue({ router, render: h => h(App) }).$mount('#app') // 卸载应用 window.unmount = () => { app.$destroy() }

侧边栏 sidebar.js 同理

/*sidebar.js 侧边栏*/ import Vue from 'vue' // 引入刚才的侧边栏组件 import App from './components/SideBar.vue' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); Vue.config.productionTip = false const app =new Vue({ router, render: h => h(App) }).$mount('#app') // 卸载应用 window.unmount = () => { app.$destroy() }

这边提一嘴 官方的配置 我就直接贴图 想了解的可以直接去看官网

  • 开启umd模式,优化内存和性能

2024-08-05T05:56:52.png

2024-08-05T05:56:52.png


重点是 vue.config.js 这个文件
2024-08-05T05:56:58.png

2024-08-05T05:56:58.png

const {defineConfig} = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, // 必须加上 devServer: { headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true', }, }, publicPath: './', assetsDir: 'static', pages: { // 原有的index入口 可有可无 // index: { // entry: './src/main.js', // template: 'public/index.html', // filename: 'index.html', // title: '首页', // }, // // 声明侧边栏入口文件 sidebar: { entry: './src/sidebar.js', template: 'public/index.html', filename: 'sidebar.html', title: '侧边栏', }, // 声明顶部栏入口文件 header: { entry: './src/header.js', template: 'public/index.html', filename: 'header.html', title: '头部', }, }, })

至此改造完成

对 子项目 进行打包

npm run build
等待片刻 打包成功!!!

2024-08-05T05:57:06.png

2024-08-05T05:57:06.png

浏览器打开网页看看效果

2024-08-05T05:57:10.png

2024-08-05T05:57:10.png

这个时候 可以开始配置nginx

我直接 将打包后的文件放在我的这个目录下
\
2024-08-05T05:57:16.png

2024-08-05T05:57:16.png

打开nginx 的配置文件 nginx.conf
配置代理 和 跨域

nginx)

location /likefr { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; if ($request_method = 'OPTIONS') { return 204; } root html/; try_files $uri.html $uri $uri/ =404; }
  • try_files 不了解的小伙伴可以上百度查查

最后记得刷新nginx 的配置

nginx -s reload

验证下是否生效
浏览器 请求
ip + nginx代理路径 + 之前我们的子项目打包后的路由名

2024-08-05T05:58:45.png

2024-08-05T05:58:45.png

成功访问

接着回到我们的主项目

在你的vue中 加入 初始化micro-app标签

侧边栏

<micro-app name='sidebar' url='http://192.168.5.208/likefr/sidebar.html' disable-memory-router @datachange="sidebarHandler"></micro-app>

顶部栏

<micro-app name='header' url='http://192.168.5.208/likefr/header.html' disable-memory-router @datachange="headerHandler"></micro-app>

最终效果

2024-08-05T05:58:54.png

附上主项目完整代码

App.vue

<template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App', created() { this.$router.push('/') } } </script> <style> *, body { margin: 0; padding: 0; } #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; width: 100vw; height: 100vh; } </style>

HomeView.vue

<template> <div class="home"> <el-container> <el-header> <micro-app name='header' url='http://192.168.5.208/likefr/header.html' disable-memory-router @datachange="headerHandler"></micro-app> </el-header> <el-container> <el-main> <!-- <router-view/>--> <el-button @click="navbar"> 发送消息给顶部栏 </el-button> <el-button @click="sidebar"> 发送消息给顶侧边栏 </el-button> </el-main> <el-aside width="200px"> <micro-app name='sidebar' url='http://192.168.5.208/likefr/sidebar.html' disable-memory-router @datachange="sidebarHandler"></micro-app> </el-aside> </el-container> <el-footer> <el-tabs type="border-card" style="height: 238px"> <el-tab-pane label="用户管理">用户管理</el-tab-pane> <el-tab-pane label="配置管理">配置管理</el-tab-pane> <el-tab-pane label="角色管理">角色管理</el-tab-pane> <el-tab-pane label="定时任务补偿">定时任务补偿</el-tab-pane> </el-tabs> </el-footer> </el-container> </div> </template> <script> import microApp from "@micro-zoe/micro-app"; export default { name: 'HomeView', data() { return { count: 0 } }, methods: { navbar() { this.count++ // 发送数据给子应用 my-app,setData第二个参数只接受对象类型 microApp.setData('header', {msg: '111111111111111' + this.count}) }, sidebar() { this.count++ // 发送数据给子应用 my-app,setData第二个参数只接受对象类型 microApp.setData('sidebar', {msg: '222222222222222' + this.count}) }, // 处理收到的数据 headerHandler(e) { this.$message.success('主应用收到顶栏数据' + JSON.stringify(e)) }, sidebarHandler(e) { this.$message.success('主应用收到侧栏数据' + e) } } } </script> <style> .el-header { padding: 0 !important; background-color: #B3C0D1; color: #333; text-align: center; line-height: 60px; } .el-footer { padding: 0 !important; background-color: #B3C0D1; text-align: center; height: 240px !important; } .el-aside { background: #D3DCE6; text-align: center; line-height: 200px; } .el-main { background-color: #E9EEF3; color: #333; text-align: center; width: 100%; height: calc(100vh - 60PX - 240PX); } </style>

"感谢大家阅读本文,希望能对大家有所帮助,同时,也欢迎大家留下宝贵的意见和建议,如果你对本文有更好的想法 随时可以提出 我很乐意接收更好的创意!让我们共同进步,共同成长。祝大家学习进步,工作顺利"

参考文献

Nginx配置跨域请求 Access-Control-Allow-Origin *
MicroApp 常见问题
个人博客

最后修改:2025 年 03 月 21 日
如果觉得我的文章对你有用,请随意赞赏