若依vue3 前端微应用改造

news2025/1/23 9:32:36

一、前言

这篇是记录解决若依vue3版本微应用改造,但是自己之前也试过vue-element-admin框架的微应用改造,前端主流的微应用技术不怎么挑框架的,而且注入方式大同小异。但自己之前尝试的时候踩过很多坑,但是确实比较麻烦,需要耐心研究,但成功的话会提升很多,而且也为之后的开发打好了基础,因此记录下可供大家参考。

二、基座框架

若依vue3版本源码地址:RuoYi-Cloud: 🎉 基于Spring Boot、Spring Cloud & Alibaba的分布式微服务架构权限管理系统,同时提供了 Vue3 的版本

特别注意

  • 若依框架拉下来需要开启后端服务器才可以跑,我是成功跑了以后,再把请求的数据暂时在前端先写成固定的,这样方便调试。请先完成拉下代码成功跑起来这一步再继续看下面哈。
  • 另外安装依赖尽量不要用镜像,yarn 或者 npm install都可以,至于为什么可以看官网。

那么如何改成固定的数据呢?这里有几处的数据需要改一下,请看下面:

1,改造登录方法

由于登录是调用store里面login的方法,这里用到了promise像后端请求,所以需要注掉一些内容;

login方法截图

 token可以复制浏览器网络请求回来的token值:

setToken("eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjJiMjUxZjA3LTc3NjUtNDQ1NC04MWM2LWQ3MDFkYmNmZTNlZiJ9.WtrolkMlQL5-8ZH78niAuNmJo5vsJzu2VJUBT4sopInf4-DP9JMsy_vkVN9pvu4fekZiEuEk1vR3jvU4dki-Nw")

注释掉getInfo方法中以下的代码 

getInfo方法

 注释掉logout方法中以下的代码:

 加上//todo下面的内容:

 this.token = ''
            this.roles = []
            this.permissions = []
            removeToken()
            resolve()
        })

2,改造store/modules/permission.js里面的路由信息

因为原来路由是向后端请求来的,所以我们需要把返回的值直接写死,如下注释掉promise请求的内容。

generateRoutes

 路由信息如下,直接让res等于它即可;

 var res = {
          msg: "操作成功",
          code: 200,
          data: [
            // 首页
            {
              name: "index",
              path: "/index",
              hidden: false,
              redirect: "noRedirect",
              component: "Layout",
              alwaysShow: true,
              meta: {
                title: "首页",
                icon: "fall",
                noCache: false,
                link: null,
              },
              //系统管理
            {
              name: "System",
              path: "/system",
              hidden: false,
              redirect: "noRedirect",
              component: "Layout",
              alwaysShow: true,
              meta: {
                title: "系统管理",
                icon: "fall",
                noCache: false,
                link: null,
              },
              children: [
                {
                  name: "User",
                  path: "user",
                  hidden: false,
                  component: "system/user/index",
                  meta: {
                    title: "用户管理",
                    icon: "user",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Role",
                  path: "role",
                  hidden: false,
                  component: "system/role/index",
                  meta: {
                    title: "角色管理",
                    icon: "peoples",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Menu",
                  path: "menu",
                  hidden: false,
                  component: "system/menu/index",
                  meta: {
                    title: "菜单管理",
                    icon: "tree-table",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Dept",
                  path: "dept",
                  hidden: false,
                  component: "system/dept/index",
                  meta: {
                    title: "部门管理",
                    icon: "tree",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Post",
                  path: "post",
                  hidden: false,
                  component: "system/post/index",
                  meta: {
                    title: "岗位管理",
                    icon: "post",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Dict",
                  path: "dict",
                  hidden: false,
                  component: "system/dict/index",
                  meta: {
                    title: "字典管理",
                    icon: "dict",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Config",
                  path: "config",
                  hidden: false,
                  component: "system/config/index",
                  meta: {
                    title: "参数设置",
                    icon: "edit",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Notice",
                  path: "notice",
                  hidden: false,
                  component: "system/notice/index",
                  meta: {
                    title: "通知公告",
                    icon: "message",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Log",
                  path: "log",
                  hidden: false,
                  redirect: "noRedirect",
                  component: "ParentView",
                  alwaysShow: true,
                  meta: {
                    title: "日志管理",
                    icon: "log",
                    noCache: false,
                    link: null,
                  },
                  children: [
                    {
                      name: "Operlog",
                      path: "operlog",
                      hidden: false,
                      component: "monitor/operlog/index",
                      meta: {
                        title: "操作日志",
                        icon: "form",
                        noCache: false,
                        link: null,
                      },
                    },
                    {
                      name: "Logininfor",
                      path: "logininfor",
                      hidden: false,
                      component: "monitor/logininfor/index",
                      meta: {
                        title: "登录日志",
                        icon: "logininfor",
                        noCache: false,
                        link: null,
                      },
                    },
                  ],
                },
              ],
            },
            //系统监控
            {
              name: "Monitor",
              path: "/monitor",
              hidden: false,
              redirect: "noRedirect",
              component: "Layout",
              alwaysShow: true,
              meta: {
                title: "系统监控",
                icon: "fall",
                noCache: false,
                link: null,
              },
              children: [
                {
                  name: "Online",
                  path: "online",
                  hidden: false,
                  component: "monitor/online/index",
                  meta: {
                    title: "在线用户",
                    icon: "online",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Job",
                  path: "job",
                  hidden: false,
                  component: "monitor/job/index",
                  meta: {
                    title: "定时任务",
                    icon: "job",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Druid",
                  path: "druid",
                  hidden: false,
                  component: "monitor/druid/index",
                  meta: {
                    title: "数据监控",
                    icon: "druid",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Server",
                  path: "server",
                  hidden: false,
                  component: "monitor/server/index",
                  meta: {
                    title: "服务监控",
                    icon: "server",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Cache",
                  path: "cache",
                  hidden: false,
                  component: "monitor/cache/index",
                  meta: {
                    title: "缓存监控",
                    icon: "redis",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "CacheList",
                  path: "cacheList",
                  hidden: false,
                  component: "monitor/cache/list",
                  meta: {
                    title: "缓存列表",
                    icon: "redis-list",
                    noCache: false,
                    link: null,
                  },
                },
              ],
            },
            //系统工具
            {
              name: "Tool",
              path: "/tool",
              hidden: false,
              redirect: "noRedirect",
              component: "Layout",
              alwaysShow: true,
              meta: {
                title: "系统工具",
                icon: "fall",
                noCache: false,
                link: null,
              },
              children: [
                {
                  name: "Build",
                  path: "build",
                  hidden: false,
                  component: "tool/build/index",
                  meta: {
                    title: "表单构建",
                    icon: "build",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Gen",
                  path: "gen",
                  hidden: false,
                  component: "tool/gen/index",
                  meta: {
                    title: "代码生成",
                    icon: "code",
                    noCache: false,
                    link: null,
                  },
                },
                {
                  name: "Swagger",
                  path: "swagger",
                  hidden: false,
                  component: "tool/swagger/index",
                  meta: {
                    title: "系统接口",
                    icon: "swagger",
                    noCache: false,
                    link: null,
                  },
                },
              ],
            },
            //若依官网
            {
              name: "Http://ruoyi.vip",
              path: "http://ruoyi.vip",
              hidden: false,
              component: "Layout",
              meta: {
                title: "若依官网",
                icon: "guide",
                noCache: false,
                link: "http://ruoyi.vip",
              },
            },
          ],
        };

 3,注释掉登录页的验证码的相关代码

大概步骤如上,可以试试能不能本地启动了,启动后相关页面的表格数据请求不到是正常的。

完成以上的准备工作可以开始微应用注入了。

三、主流微前端框架

1,阿里Qiankun:

官方文档:介绍 - qiankunhttps://qiankun.umijs.org/zh/guideqiankun我踩的坑比较多,所以本篇不涉及,后面单独更新哈;

2,京东MicroApp:

官方文档:MicroAppDescriptionhttps://cangdu.org/micro-app/docs.html#/zh-cn/start(1)主应用

特别注意:主应用路由如果是hash模式,子应用只能是hash模式,主应用如果是history模式,子应用可以是history或者hash模式。

 history: createWebHistory(process.env.BASE_URL)

  • 步骤一:安装依赖

安装依赖:npm i @micro-zoe/micro-app --save 或 yarn add micro-zoe/micro-app --save

  • 步骤二:入口文件引入

// 放在顶部

import microApp from'@micro-zoe/micro-app'

microApp.start()

  • 步骤三:分配个路由给子应用

在store/modules/permission.js的res里面添加一个子应用的路由

            //子应用
            {
              name: "micro",
              path: "/micro-app",
              hidden: false,
              redirect: "noRedirect",
              component: "Layout",
              alwaysShow: true,
              meta: {
                title: "子应用",
                icon: "fall",
                noCache: false,
                link: null,
              },
              children:[
                {
                  name: "micro1",
                  path: "home",
                  hidden: false,
                  component: "micro/micro1/index",
                  meta: {
                    title: "子应用1",
                    icon: "user",
                    noCache: true,
                    link: null,
                  },
                },
                {
                  name:"micro2",
                  path:"about",
                  hidden:false,
                  component:"micro/micro1/index",
                  meta:{
                    title:"子应用2",
                    icon: "user",
                    noCache: true,
                    link: null,
                  }
                }
              ]
            },
  • 步骤四:创建子应用挂载的页面

views文件夹里面新建micro/micro1/index.vue页面

<template>
  <div class="miro-son1">
    <micro-app
      name="micro1" //分配给子应用的children的name
      url="http://localhost:8080/" //子应用跑起来的地址
      baseRoute="/micro-app" //分配子应用的path
      keep-alive //缓存,一定要有
    ></micro-app>
  </div>
</template>

<script>
export default {
  name: "",
  setup() {
    return {};
  },
};
function onBeforeshow(){
  console.log('即将重新渲染,初始化时不执行')
}

</script>

<style scoped lang="scss">
</style>

这个新建的页面不需要自己去挂载app-main里面,不用多此一举的。

(2)子应用

我自己是直接用脚手架创建了vue3的子项目

  • 步骤一:src文件夹下新建public_path.js文件
// __MICRO_APP_ENVIRONMENT__和__MICRO_APP_PUBLIC_PATH__是由micro-app注入的全局变量
if (window.__MICRO_APP_ENVIRONMENT__) {
  // eslint-disable-next-line
  __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
}
  • 步骤二:main.js引入这个文件,并导出三个方法

import './public_path' // 顶部顶部

// -------------------分割线-umd模式------------------ //
export async function mount(props) {
  // app.createApp(App)
  app.mount(props?.container?.querySelector("#app") || "#app");
  
  console.log("微应用vue2渲染了 -- 来自umd-mount");
}
//卸载应用
export async function unmount() {
  app.destroy();
  app.$el.innerHTML = "";
  app = null;
  console.log("微应用vue2卸载了 -- 来自umd-unmount");
}
export async function bootstrap() {}

// 微前端环境下,注册mount和unmount方法
if (window.__MICRO_APP_ENVIRONMENT__) {
  window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount };
} else {
  // 非微前端环境直接渲染
  mount();
}
  • 步骤三: 监听keep-alive状态
// 监听keep-alive模式下的应用状态
window.addEventListener('appstate-change', function (e) {
  if (e.detail.appState === 'afterhidden') {
    console.log('已卸载')
  } else if (e.detail.appState === 'beforeshow') {
    // console.log(routes);
    // console.log(e);
    
    console.log('即将重新渲染')
    const baseRoute = window.__MICRO_APP_BASE_ROUTE__ ;
    const p = window.location.pathname;
      const paramsBeginIndex = p.indexOf("?");
      const path = p.substring(baseRoute.length, paramsBeginIndex === -1 ? undefined : paramsBeginIndex);
      // const query = convertHrefSearch(window.location.search);
      console.log(baseRoute);
      console.log(path);
      
      
      //todo
      if (routes) {
        if (path) {
          // if (path === "home") {
          //   window.$router.replace({ path: "/", query });
          // }
          var completePath = baseRoute+path;
          console.log(completePath);
          routes.replace({ path:completePath });
        }
      } else console.warn("[MicroAppSetup]: 没有发现window.$router路由对象");
  } else if (e.detail.appState === 'aftershow') {
    console.log('已经重新渲染')
  }
})
  • 步骤四:子应用配置跨域
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8080,                             // 修改端口
    headers: {
      'Access-Control-Allow-Origin': '*',   // 设置跨域
    },
  }
})

好了,差不多可以跑了,耐心的调试会成功的,当然关于如何父子应用通信这篇就不说了,可以参考官方文档,后面自己尝试了后再更新。

另外,如果真的诚心想啃下微前端这块硬骨头的话,大家可以加一下官网的微信群,我就是keep-alive的问题出现了问题,求教大佬,慢慢研究出来的。加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Javascript知识【jQuery样式操作案例:jQuery隔行换色】

&#x1f482; 个人主页: 爱吃豆的土豆&#x1f91f; 版权: 本文由【爱吃豆的土豆】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 &#x1f3c6;人必有所执&#xff0c;方能有所成&#xff01; &#…

【element-ui】 el-table 表格动态合并相同数据单元格最全教程,可指定列+自定义合并条件,附完整代码

el-table合并单元格 1.固定合并 官方挺提供的合并具体某行列的方法:el-table合并行或列通过给table传入span-method方法可以实现合并行或列&#xff0c;方法的参数是一个对象&#xff0c;里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。 …

CSS中的伪类和伪元素(详细)

这篇想要跟大家分享的是css中的伪类和伪元素&#xff0c;有任何问题可以私聊我或者评论哦&#xff01; 首先&#xff0c;我们先来想一下 一、引入伪类跟伪元素的原因&#xff1f; 伪类和伪元素的引入是因为在文档树里有些信息无法被充分描述 比如CSS没有“段落的第一行”、…

[error] Error: Fail to open IDE 问题解决

问题描述&#xff1a;接手前辈的微信小程序项目&#xff08;uni-app搭建&#xff09;&#xff0c;使用HBuilder编译器&#xff0c;&#xff0c;控制台报 [error] Error: Fail to open IDE 错误原因一&#xff1a;微信小程序AppID错误解决方法&#xff1a;如图点击项目目录 mani…

wangeditor5在vue3中的全使用过程(图片上传、附件上传、工具栏配置、编辑器配置)

1、参考官方的wangeditor5-for-vue3的开发手册 官方文档地址&#xff1a;https://clinfc.github.io/wangeditor5-for-vue3/guide/ 说明为说明要编写这编博客文章&#xff1f; 官方文档的使用手册对于新手来说比较的难看懂&#xff0c;写的也不够详细&#xff0c;源码的封装比较…

vue3+vite项目配置ESlint、pritter插件

前言 入行前端工作将近两年多时间了&#xff08;如果算上实习&#xff09;&#xff0c;从一开始vue2入门&#xff0c;到现在vue3前端变化是真的快&#xff0c;刚了解webpack搭建项目流程&#xff0c;vite又横空出世&#xff0c;不得不说前端变化真的太快了&#xff0c;所以只有…

【JavaScript】DOM和事件简介和文档加载流程以及DOM查询(上)案例(附源码)

&#x1f41a;作者简介&#xff1a;苏凉&#xff08;专注于网络爬虫&#xff0c;数据分析&#xff0c;正在学习前端的路上&#xff09; &#x1f433;博客主页&#xff1a;苏凉.py的博客 &#x1f310;系列总专栏&#xff1a;web前端基础教程 &#x1f451;名言警句&#xff1a…

自己的智能AI聊天机器人,可自定义头像,免费html源码分享,粘贴即用!

1.展示效果效果预览图&#xff1a;新增小功能&#xff1a;① 在原有的基础上加入了本地实时存档的功能&#xff0c;按照下面的步骤便可以随时在本地查看以往和智能AI所有的聊天记录哦&#xff01;再也不用担心关闭网页后先前的聊天内容全部消失啦&#xff01;PS&#xff1a;最新…

解决宝塔 Nginx 跨域问题Access-Control-Allow-Origin

何为跨域&#xff1f; 1、资源跳转&#xff1a; A链接、重定向、表单提交 2.资源嵌入&#xff1a; <link>、<script>、<img>、<frame>等dom标签&#xff0c;还有样式中background:url()、font-face()等文件外链 3.脚本请求&#xff1a; js发起的ajax请…

商城系统需求分析

文章目录一、引言1.1项目背景1.2 前期工作二、技术概述三、功能需求3.1 功能块划分3.2 功能块描述3.2.1 面向用户部分功能&#xff1a;3.2.2 后台管理部分功能&#xff1a;四、性能需求4.1 数据精确度4.2 适应性五、系统流程图5.1 顾客与管理员流程图如下5.2 订单处理流程说明六…

VUE动态切换皮肤 VUE动态切换背景图片 操作 / VUE 主题切换

上正文 使用&#xff1a;root &#xff0c;var&#xff08;&#xff09;函数实现 1. 创建皮肤或主题 css目录 一个公共主题文件 theme.css&#xff0c;一个main.js引入文件theme-all.css&#xff0c;一个单独的 主题样式文件 theme-12.css 2. 定义css文件中所要切换的主题的…

vue(绑定style属性)

以对象方式绑定style属性 <div id"app"> <!-- 在行内属性中书写样式 --> <div style"color:royalblue ; font-size: 48px;">黄绥睿真帅个鬼</div> <!-- 把行内属性改造成对象&#xff0c;以对象方式绑定style属性 外部增加{}&a…

【进阶】TS 中的 类型断言 和 泛型

类型断言 作用 : 手动指定值的具体类型 ( 缩写值的范围 ) 应用场景 1 获取 DOM 元素的时候指定具体元素 示例 : const box document.getElementById(img) console.log(box.src) // ts报错错误内容 : 解析 &#xff1a; 上述语法在 js 中可以直接使用, 但是 TS 中就不行…

vue 动态样式绑定 class/style

简介&#xff1a; 字符串写法&#xff1a;类名不确定&#xff0c;要动态获取 对象写法&#xff1a;要绑定多个样式&#xff0c;个数确定&#xff0c;名字确定&#xff0c;但不确定用不用。 数组写法&#xff1a;要绑定多个样式&#xff0c;个数不确定&#xff0c;名字不确定。…

HTML基础 - HTML表格

HTML基础 - HTML表格 1.无表头的表格 <table> <tr> <td> <table>标签代表的是表 <tr>标签代表的是行 <td>标签代表的是列 在html页面中的表格来着&#xff0c;就和excl的表格不一样喽&#xff0c;咱自己有自己的规则&#xff1a; 这就是…

这一次,彻底搞懂箭头函数

一、箭头函数的特点 1. 相比普通函数&#xff0c;箭头函数有更加简洁的语法。 普通函数 function add(num) {return num 10 }箭头函数 const add num > num 10;2. 箭头函数不绑定this&#xff0c;会捕获其所在上下文的this&#xff0c;作为自己的this。 这句话需要注意的…

若依(ruoyi)字典管理插件实现思路探究

一个UI表单的构成&#xff0c;避免不了下拉框&#xff0c;多选框等标签&#xff0c;在开发这些标签时&#xff0c;通常会请求后台接口获取字典值进行动态渲染。定制化开发虽然实现简单&#xff0c;但会产生大量重复工作&#xff0c;解决这类问题的思路有哪些&#xff1f;文章对…

chrome插件开发时跨域问题解决方案

这是一个没有套路的前端博主&#xff0c;热衷各种前端向的骚操作&#xff0c;经常想到哪就写到哪&#xff0c;如果有感兴趣的技术和前端效果可以留言&#xff5e;博主看到后会去代替大家踩坑的&#xff5e;接下来的几篇都是uni-app的小实战&#xff0c;有助于我们更好的去学习u…

Vue在HTML中如何使用

&#x1f440;Vue是什么 一套用于构建用户界面的渐进式JavaScript框架。 构建用户界面&#xff1a;数据变成界面渐进式&#xff1a;Vue可以自底向上逐层的应用&#x1f440;Vue如何使用 一、引入vue.js <script src"./js/vue.js"></script> 二、准备一个…

HBuilderX uni-app简单实现静态登录页面(实例)

本章用到......uni-app页面跳转uni.navigateTo方法、uni.navigateBack方法。uni-app简单实现邮箱验证码发送点击后读秒样式。登录账号、密码正则表达式验证等 适合刚入门的小伙伴&#xff0c;大佬就没必要看了 静态页面&#xff01;静态页面&#xff01;没有绑定后端数据接口…