您的位置:首页 > 财经 > 金融 > qiankun实现子应用tab页签切换缓存页面

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

2025/1/16 7:55:12 来源:https://blog.csdn.net/weixin_42912237/article/details/140207283  浏览:    关键词: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 // 开启样式隔离}},
]
  1. 修改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
  1. 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: '',}// 初始化stateconst 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
}
  1. 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 = falseincludedRoutes.forEach(item => {if (subNameArr.includes(item)) {isInclude = true}})// 子应用没有缓存的页面,卸载子应用if (!isInclude) {activeApps[key].unmount()delete activeApps[key]}}
}
  1. 子应用入口
    在这里插入图片描述
  2. 在tab页面关闭时调用unmountMicroApps 方法

子应用

  1. user.js加上这段代码,解决主子应用路由冲突
    在这里插入图片描述

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com