qiankun实现子应用tab页签切换缓存页面

实现背景

项目中是使用的jeecg-boot低代码构建的前端开发环境,由于后期各个模块代码越来越多,打包慢,分支管理麻烦,领导要求使用微前端,每个模块拆分为子应用。

拆分子应用

由于jeecg里面自带qiankun,所以改造微前端我们使用qiankun来做

为了方便我们使用的qiankun自动挂载(registerMicroApps)的方式实现的

新的问题?

registerMicroApps方式使用了一段时间后,需求上需要切换tab页面时缓存子应用页面,页签关闭取消缓存,从菜单点击页面刷新。

从网上找了一些registerMicroApps实现缓存的方法,不是很适用,比如说:
https://zhuanlan.zhihu.com/p/548520855,3.1描述的方式实现,以及
https://blog.csdn.net/lunahaijiao/article/details/134657734,方案二实现方式。这两种都是registerMicroApps自动挂载的方式实现缓存页面。但是出现的问题是:一个子应用多个缓存页面就会出问题了

通过loadMicroApp实现

主应用

  1. 首先,主应用修改apps.js

    const _apps = [
    {
    name: 'app1,
    entry:
    process.env.NODE_ENV === 'development'
    ? 'http://localhost:9529/'
    : document.querySelector('html').dataset.app1Url,
    container: '#contentApp1',
    activeRule: 'app1', //路由匹配
    sandbox: {
    strictStyleIsolation: true // 开启样式隔离
    }
    },
    {
    name: 'app2',
    entry:
    process.env.NODE_ENV === 'development'
    ? 'http://localhost:3099/'
    : document.querySelector('html').dataset.app2Url,
    container: '#contentApp2',
    activeRule: 'app2', //路由匹配
    sandbox: {
    strictStyleIsolation: true // 开启样式隔离
    }
    },
    ]

  2. 修改index.js

    /**

    • qiankun配置
      */
      import {
      loadMicroApp,
      } from 'qiankun'
      import { apps } from './apps'
      import { getProps, initGlState } from './state'
      import { prefetchApps } from 'qiankun';

    prefetchApps(apps);

    /**

    • 微应用注册
      */
      function registerApps(item) {
      const loader = loadMicroApp({
      ...item,
      props: {
      ...getProps(),
      }
      }, {
      sandbox: {
      experimentalStyleIsolation: true, // 开启沙箱模式,实验性方案
      }
      })
      // 定义全局状态
      initGlState()
      return loader
      }

    export default registerApps

  3. state.js更改

    /**
    *公共数据
    */
    import { initGlobalState } from 'qiankun'
    import store from '../store'
    import Vue from 'vue'
    import { ACCESS_TOKEN, USER_NAME } from '@/store/mutation-types'
    // 公共组件

    //定义传入子应用的数据
    export function getProps() {
    return {
    data: {
    publicPath: process.env.BASE_URL,
    token: Vue.ls.get(ACCESS_TOKEN)
    }
    }
    }

    /**

    • 定义全局状态,并返回通信方法,在主应用使用,微应用通过 props 获取通信方法。
    • @param state 主应用穿的公共数据
      */
      export function initGlState() {
      const info = {
      userName: Vue.ls.get(USER_NAME),
      isLogin: true,
      closeCurrent: false,
      produceTabsChange: 1,
      approvalParams: '',
      }
      // 初始化state
      const actions = initGlobalState(info)
      // 设置新的值
      actions.setGlobalState(info)
      // 注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。
      actions.onGlobalStateChange((newState, prev) => {
      if (!newState.isLogin) {
      store.dispatch('Logout').then(() => {
      window.location.reload()
      })
      }
      if (newState.closeCurrent) {
      store.dispatch('setCloseTab', true)
      actions.setGlobalState({ closeCurrent: false })
      }
      })
      // 将action对象绑到Vue原型上,为了项目中其他地方使用方便
      Vue.prototype.$actions = actions
      }
  4. mian.js 修改

    let activeApps = {}
    router.beforeEach((to, from, next) => {
    const conf = apps.find(item => to.path.includes(item.activeRule))
    if (conf) {
    store.dispatch('setOpenQianKun', true)
    const cacheMicro = activeApps[conf.activeRule]
    // 已缓存应用
    if (cacheMicro) {
    next()
    return
    }
    // 未缓存应用
    activeApps[conf.activeRule] = registerApps({ ...conf })
    next()
    } else {
    unmountMicroApps()
    store.dispatch('setOpenQianKun', false)
    next()
    }
    })
    export function unmountMicroApps () {
    for (const key in activeApps) {
    // 缓存的页面
    const includedRoutes = Vue.ls.get(CACHE_INCLUDED_ROUTES) || []
    // 子应用所有的页面
    const subNameArr = Vue.ls.get(CACHE_SUB_ROUTES)[key]
    let isInclude = false
    includedRoutes.forEach(item => {
    if (subNameArr.includes(item)) {
    isInclude = true
    }
    })
    // 子应用没有缓存的页面,卸载子应用
    if (!isInclude) {
    activeApps[key].unmount()
    delete activeApps[key]
    }
    }
    }

  5. 子应用入口

  6. 在tab页面关闭时调用unmountMicroApps 方法

子应用

  1. user.js加上这段代码,解决主子应用路由冲突

大致就是这些改造,还有一些页面的优化没有贴上来,后续会梳理出不含业务的代码,有需要的朋友可以联系

相关推荐
web182854825122 分钟前
ctfshow-web 151-170-文件上传
前端·状态模式
轻口味7 分钟前
【每日学点鸿蒙知识】Web请求支持Http、PDF展示、APP上架应用搜索问题、APP备案不通过问题、滚动列表问题
前端·http·harmonyos
一棵开花的树,枝芽无限靠近你16 分钟前
【PPTist】表格功能
前端·笔记·学习·编辑器·ppt·pptist
龙哥·三年风水31 分钟前
workman服务端开发模式-应用开发-vue-element-admin挂载websocket
分布式·websocket·vue
马船长1 小时前
RCE-PLUS (学习记录)
java·linux·前端
学前端的小朱1 小时前
修改输出资源的名称和路径、自动清空上次打包资源
前端·webpack·打包工具
嘤嘤怪呆呆狗1 小时前
【开发问题记录】执行 git cz 报require() of ES Module…… 错误
前端·javascript·vue.js·git·vue
夜斗(dou)2 小时前
谷歌开发者工具 - 网络篇
前端·网络·chrome devtools
常常不爱学习2 小时前
CSS盒子模型(溢出隐藏,块级元素和行级元素的居中对齐,元素样式重置)
前端·css
风抽过的烟头2 小时前
Python提取字符串中的json,时间,特定字符
前端·python·json