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加上这段代码,解决主子应用路由冲突

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

相关推荐
许___20 小时前
Vue使用原生方式把视频当作背景
前端·javascript·vue.js
萌萌哒草头将军21 小时前
尤雨溪强烈推荐的这个库你一定要知道 ⚡️⚡️⚡️
前端·vue.js·vite
2401_8784545321 小时前
Vue 核心特性详解:计算属性、监听属性与事件交互实战指南
前端·vue.js·交互
1024小神1 天前
uniapp+vue3+vite+ts+xr-frame实现ar+vr渲染踩坑记
前端
测试界清流1 天前
基于pytest的接口测试
前端·servlet
知识分享小能手1 天前
微信小程序入门学习教程,从入门到精通,自定义组件与第三方 UI 组件库(以 Vant Weapp 为例) (16)
前端·学习·ui·微信小程序·小程序·vue·编程
trsoliu1 天前
多仓库 Workspace 协作机制完整方案
前端
啦工作呢1 天前
数据可视化 ECharts
前端·信息可视化·echarts
NoneSL1 天前
Uniapp UTS插件开发实战:引入第三方SDK
前端·uni-app
trsoliu1 天前
Claude Code Templates
前端·人工智能