完善刷新页面展示bug
This commit is contained in:
@@ -14,6 +14,25 @@ import {
|
||||
import { addView, activeFullPath, visitedViews } from './tagsViewStore.uts'
|
||||
import { hasAdminModuleAccess } from '@/layouts/admin/utils/role.uts'
|
||||
|
||||
// ============================================
|
||||
// Tabs 持久化 keys(使用 sessionStorage,与 token 策略一致)
|
||||
// sessionStorage 在同一标签页 F5 刷新后保留,关闭标签页后自动清除
|
||||
// ============================================
|
||||
const TAB_STORAGE_KEY = 'admin_opened_tabs'
|
||||
const ACTIVE_ROUTE_KEY = 'admin_active_route'
|
||||
const LAST_SUB_STORAGE_KEY = 'admin_last_sub_by_menu'
|
||||
|
||||
/** 将当前 tabs / activeRouteId / lastSubIdByMenu 写入 sessionStorage */
|
||||
function persistNavState(): void {
|
||||
// #ifdef H5
|
||||
try {
|
||||
sessionStorage.setItem(TAB_STORAGE_KEY, JSON.stringify(tabs.value))
|
||||
sessionStorage.setItem(ACTIVE_ROUTE_KEY, activeRouteId.value)
|
||||
sessionStorage.setItem(LAST_SUB_STORAGE_KEY, JSON.stringify(lastSubIdByMenu.value))
|
||||
} catch (_) {}
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签页类型
|
||||
*/
|
||||
@@ -120,6 +139,9 @@ export function openRoute(routeId: string, addTab: boolean = true): void {
|
||||
// 添加到标签页
|
||||
if (addTab) {
|
||||
addTabItem(route)
|
||||
} else {
|
||||
// 即使不新增 tab,activeRouteId 变化了也要持久化
|
||||
persistNavState()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +172,9 @@ function addTabItem(route: RouteRecord): void {
|
||||
// 更新新版 TagsViewStore
|
||||
addView(route, route.path)
|
||||
activeFullPath.value = route.path
|
||||
|
||||
// 持久化到 sessionStorage
|
||||
persistNavState()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,6 +203,8 @@ export function closeTab(tabId: string): void {
|
||||
}
|
||||
|
||||
tabs.value.splice(index, 1)
|
||||
// 持久化
|
||||
persistNavState()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,6 +219,8 @@ export function closeOtherTabs(keepTabId: string): void {
|
||||
if (!stillExists) {
|
||||
openRoute(keepTabId, false)
|
||||
}
|
||||
// 持久化
|
||||
persistNavState()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,6 +234,8 @@ export function closeAllTabs(): void {
|
||||
if (homeTab) {
|
||||
openRoute(homeTab.id, false)
|
||||
}
|
||||
// 持久化
|
||||
persistNavState()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +253,7 @@ export function toggleSubSider(): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化导航状态
|
||||
* 初始化导航状态(首次进入 / 恢复失败时的兜底)
|
||||
* 在 AdminLayout 组件 onMounted 时调用
|
||||
*/
|
||||
export function initNavState(): void {
|
||||
@@ -244,6 +275,86 @@ export function initNavState(): void {
|
||||
openRoute('home_index', false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 sessionStorage 恢复导航状态(F5刷新后调用)
|
||||
* - 校验每个缓存 tab 的路由是否仍然存在
|
||||
* - 校验是否仍有权限
|
||||
* - 过滤无效项后重建 tabs
|
||||
* - 恢复 activeRouteId 和菜单高亮
|
||||
* @returns true=恢复成功,false=无有效缓存或恢复失败(调用方应走 initNavState 兜底)
|
||||
*/
|
||||
export function restoreNavState(): boolean {
|
||||
// #ifdef H5
|
||||
try {
|
||||
const rawTabs = sessionStorage.getItem(TAB_STORAGE_KEY)
|
||||
if (!rawTabs) return false
|
||||
|
||||
const savedTabs = JSON.parse(rawTabs) as TabItem[]
|
||||
if (!Array.isArray(savedTabs) || savedTabs.length === 0) return false
|
||||
|
||||
// 校验并过滤:路由必须存在且有权限
|
||||
const validTabs = savedTabs.filter(tab => {
|
||||
const route = findRouteById(tab.id)
|
||||
if (!route) return false // 路由已不存在(文件删除或路由表变更)
|
||||
const moduleId = route.parentId ?? tab.id.split('_')[0]
|
||||
return hasAdminModuleAccess(moduleId) // 检查权限
|
||||
})
|
||||
|
||||
// 首页 tab 始终保留(防止全部被过滤后无处可去)
|
||||
const homeRoute = findRouteById('home_index')
|
||||
if (homeRoute && !validTabs.some(t => t.id === 'home_index')) {
|
||||
validTabs.unshift({
|
||||
id: homeRoute.id,
|
||||
title: homeRoute.title,
|
||||
path: homeRoute.path,
|
||||
isAffix: homeRoute.isAffix || false
|
||||
})
|
||||
}
|
||||
|
||||
if (validTabs.length === 0) return false
|
||||
|
||||
// 重建 tabs
|
||||
tabs.value = validTabs
|
||||
validTabs.forEach(tab => {
|
||||
const route = findRouteById(tab.id)
|
||||
if (route) addView(route, route.path)
|
||||
})
|
||||
|
||||
// 恢复 lastSubIdByMenu
|
||||
try {
|
||||
const rawLast = sessionStorage.getItem(LAST_SUB_STORAGE_KEY)
|
||||
if (rawLast) {
|
||||
lastSubIdByMenu.value = JSON.parse(rawLast) as Record<string, string>
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
// 恢复 activeRouteId
|
||||
const savedActive = sessionStorage.getItem(ACTIVE_ROUTE_KEY)
|
||||
const activeIsValid = savedActive != null &&
|
||||
findRouteById(savedActive) != null &&
|
||||
validTabs.some(t => t.id === savedActive)
|
||||
|
||||
const targetId = activeIsValid ? savedActive! : validTabs[0].id
|
||||
activeRouteId.value = targetId
|
||||
activeFullPath.value = findRouteById(targetId)?.path ?? ''
|
||||
|
||||
const activeRoute = findRouteById(targetId)
|
||||
if (activeRoute?.parentId) {
|
||||
activeTopMenuId.value = activeRoute.parentId
|
||||
} else {
|
||||
activeTopMenuId.value = targetId.split('_')[0]
|
||||
}
|
||||
|
||||
console.log('[AdminNav] 已从缓存恢复导航状态, tabs:', validTabs.length, 'active:', targetId)
|
||||
return true
|
||||
} catch (e) {
|
||||
console.warn('[AdminNav] 恢复导航状态失败,将走默认初始化:', e)
|
||||
return false
|
||||
}
|
||||
// #endif
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 currentPage 同步状态
|
||||
* 用于页面组件传入 currentPage prop 时的状态同步
|
||||
|
||||
Reference in New Issue
Block a user