首页 > 其他分享 >【Vue】使用iframe解决多应用整合问题(微前端)

【Vue】使用iframe解决多应用整合问题(微前端)

时间:2024-02-09 11:11:06浏览次数:23  
标签:Vue iframe 应用 前端 symbol key APP name

一、需求背景

有老系统需要重构,新做的系统需要做一个大一统的整合,类似一个分类栏目

在菜单位置罗列出有什么子系统应用,点击对应的应用菜单,展示区跳转到相应的子系统应用中

我用Excel简单描述了下系统的页面效果:

 

二、技术方案

第一种,使用iframe实现,html提供了iframe标签实现页面内访问其他页面的功能

第二种,使用微前端框架,微前端的实现原理很多,iframe或则组件,又或者远程调用....

  详细见:https://www.jianshu.com/p/0aaf0daaaeee

 

基于现实情况的考量:非专业前端开发,项目成员没有前端大神,微前端一无所知,项目初版开发周期短

我们选择的方案是使用iframe实现

 

三、落地实现

主应用web + 基础应用web 共用 基础应用server的接口

基础应用相当于认证中心,其他业务server只需要认证中心的鉴权即可

所有web使用同一个令牌做前端权限控制(同理后端)

 

iframe标签内的应用和主应用共享浏览器数据,需要保持在同一个域之内

 

1、主应用web改造

主应用本身不需要server,  都是对接基础应用的,所以新增api接口

解决web登录,跳转,退出的接口问题

 

请求基础应用的令牌携带方式和一些其他参数传递的处理也调整:

 

 vuex的用户actions的方法也要调整

这里定义如何存储用户信息,和退出时需要处理的步骤逻辑

 

因为我的token存储方式和基础应用的存储方式并不一致,同一个token以两种方式存储

在退出登录的时候,一定要同步把基础应用的token删除,那这里是把那边的逻辑代码搬过来了

(见上面logout方法调用 removeJnpfToken)

 

iframe跳转实现

首先要有侧边应用菜单的选择:

<el-aside class="sub-sys-menu">
    <img :src="appLogo" class="app-logo">
    <el-menu
        mode="vertical"
        class="sub-sys-menu-list"
        :default-active="getDefaultActiveMenu"
        @select="whenMenuItemSelect"
    >
        <el-menu-item
            v-for="(m, idx) in sysMenuList"
            :key="`menu${idx}`"
            :index="m.key"
        >
            <template slot="title">
                <div class="sub-sys-menu-item">
                    <svg-icon :icon-class="m.icon" class="sub-sys-menu-icon" />
                    <span class="sub-sys-menu-title">{{ m.name }}</span>
                </div>
            </template>
        </el-menu-item>
    </el-menu>
</el-aside>

 

默认激活的应用,和应用选中后的事件处理

    getDefaultActiveMenu() {
      if (!this.sysMenuList || this.sysMenuList.length === 0) return ''
      return this.sysMenuList[0].key
    },
    async whenMenuItemSelect(key, keyPath) {
      await this.isLoginCheck()
      const app = this.appList.find(x => x.symbol === key)
      const menu = this.sysMenuList.find(x => x.key === key)
      this.currentAppUrl = `${app.url}?Authorization=${encodeURIComponent(this.currentToken)}&time=${new Date().getTime()}`
      this.currentAppTitle = menu.name
    },

 

因为点击时不是路由跳转,所以手动追加是否在线判断:

async isLoginCheck() {
      try {
        await this.$store.dispatch('UserGetInfo')
      } catch (error) {
        await this.$store.dispatch('UserResetToken')
        this.$router.push({ path: '/login' })
      }
    }

 

iframe标签去除所有边框,外边距,百分百填充容器元素

 <el-main class="frame-container">
        <iframe
          frameborder="0"
          border="0"
          marginwidth="0"
          marginheight="0"
          width="100%"
          height="100%"
          :src="currentAppUrl"
        />
      </el-main>

  

数据定义部分:

  data() {
    return {
      color: 'red',
      appLogo: require('@/assets/sidelogo-light.png'),
      sysMenuList: [
        { name: '经营场所', icon: 'jxxcs', key: 'APP-1001' },
        { name: '非经营场所', icon: 'fjyxcs', key: 'APP-1002' },
        { name: '等保测评', icon: 'dbcp', key: 'APP-1003' },
        { name: 'APP管理', icon: 'app', key: 'APP-1004' },
        { name: '系统管理', icon: 'sz', key: 'APP-1005' }
      ],
      appList: [
        { symbol: 'APP-1001', url: 'https://www.cnblogs.com/mindzone/p/17964919' },
        { symbol: 'APP-1002', url: 'https://www.bilibili.com/' },
        { symbol: 'APP-1003', url: 'http://192.168.200.45/cp-mng-web/home' },
        { symbol: 'APP-1004', url: 'https://www.cnblogs.com/mindzone' },
        { symbol: 'APP-1005', url: 'http://192.168.200.45:3000/home' }
        // { symbol: 'APP-1005', url: 'http://172.17.29.7:3000/home' }
      ],
      currentAppUrl: '',
      currentAppTitle: '',
      currentUserName: '',
      currentToken: '',
      changeFlag: false
    }
  },
  computed: {
    ...mapGetters(['userInfo', 'token'])
  },

  

 页面挂载时,同步当前用户信息:

  mounted() {
    this.currentUserName = this.userInfo.userName
    this.currentToken = `${this.token}`
  },

 

2、子应用免登录访问问题:

因为进入子应用不应该再次输入密码登录访问,在进入主应用的时候已经通过了认证中心的处理

这里以基础应用为例(本身也是子应用)进行改造调整:

 在路由权限逻辑中追加一个免登录的跳转,判断路由路径 + 请求参数是否携带令牌,如果符号则设置令牌,继续跳转

 

标签:Vue,iframe,应用,前端,symbol,key,APP,name
From: https://www.cnblogs.com/mindzone/p/18004135

相关文章

  • vue下载文件超过10M被拒绝
    原文链接:https://www.jianshu.com/p/3810d7e463b1一问题现象昨天一朋友遇到超过10M文件,springboot下载文件被拒绝的问题,是秒拒绝。第一反应是不是springboot的配置了限制,通过检查配置,代码和配置中都有文件配置的代码,最大的大小设置为200MB了,根本不存在问题。其他文件下载小......
  • 在vue中使用amis
    之前在使用amis时,是通过百度给的一个完整amis示例来用的,没有结合到自己的vue项目中,传送门:低代码平台amis学习本次简单介绍下,如何在vue中引入ami1、首先要在vue项目中引入amis的sdk引入方式有2种:(1)使用cdn方式  (2)下载sdk文件-本地引用(1)使用cdn方式,直接引用远程资源打......
  • 前端vscode+eslint代码规范
    前端使用vscode+eslint格式化规范代码格式在应用商店安装eslint,配置好eslint,根目录新增.eslintrc.jsmodule.exports={root:true,parserOptions:{parser:'babel-eslint',sourceType:'module'},env:{browser:true,node:true,es6......
  • Vue中不刷新页面,只刷新局部组件的方法
    第一步:组件后面加上v-if方法<divid="app"ref="app"><router-viewv-if="is_show"/></div>第二步:data定义一个变量控制v-ifdata(){return{is_show:true//定义一个变量控制v-if}第三步:自定义刷新局部组件方法reflash:asyncfunction(){......
  • Vue中使用Echarts
    第一步:安装echarts模块cnpminstallecharts-S第二步:在main.js中全局引入importechartsfrom'echarts'Vue.prototype.$echarts=echarts//全局引入后面用this.$echarts就能直接使用了使用方式:template中<template><el-cardclass="box-card"style=&quo......
  • element UI vue脚手架 接入cdn
    vue.config.jsmodule.exports={configureWebpack:{externals:{'element-ui':'ELEMENT',vue:'Vue'}}//externals配置来告诉Webpack不要打包它。 index.html<!DOCTYPEhtml><htmllang="en&qu......
  • 如何实现Vuex本地存储
    在前端开发中,Vuex是一款非常强大的状态管理工具,但是默认情况下,Vuex的数据是存储在内存中的,刷新页面后数据将会丢失。这往往会导致用户在刷新页面后需要重新登录等繁琐的操作。本篇文章将教会您如何实现Vuex的本地存储,让您的应用程序能够在刷新页面后依然保持用户的状态和数据。一、......
  • github action创建一个前端的自动话部署流程。
    上次是部署后端,这次是部署前端,前面的步骤都一样,后面就直接贴部署的ymlname:buildandteston:push:branches:-masterjobs:build:runs-on:ubuntu-lateststeps:-name:checkoutrespositoryuses:actions/checkout@v2-nam......
  • vue 样式绑定
    <!DOCTYPEhtml><html><head><metacharset="UTF-8"/><title>绑定样式</title><style>.basic{width:400px;height:100px;......
  • vue 监视 watch
    <!DOCTYPEhtml><html><head><metacharset="UTF-8"/><title>天气案例_深度监视</title><!--引入Vue--><scripttype="text/javascript"src="../js/vue.js"......