优化 PWA 状态恢复逻辑

This commit is contained in:
jxxghp
2025-07-09 11:07:24 +08:00
parent c7443d993e
commit 36389a5b8c
3 changed files with 25 additions and 23 deletions
+15 -2
View File
@@ -45,9 +45,13 @@ export function useDynamicHeaderTab() {
const enablePWARestore = config.enableStateRestore !== false // 默认启用 const enablePWARestore = config.enableStateRestore !== false // 默认启用
const pwaTabState = enablePWARestore ? useTabStateRestore(config.modelValue.value) : null const pwaTabState = enablePWARestore ? useTabStateRestore(config.modelValue.value) : null
// 如果启用了PWA状态恢复,先尝试恢复状态 // 标记是否已经初始化过,避免重复恢复状态
if (pwaTabState && pwaTabState.activeTab.value) { let isInitialized = false
// 如果启用了PWA状态恢复,先尝试恢复状态(仅在首次初始化时)
if (pwaTabState && pwaTabState.activeTab.value && !isInitialized) {
config.modelValue.value = pwaTabState.activeTab.value config.modelValue.value = pwaTabState.activeTab.value
isInitialized = true
} }
const tabConfig: DynamicHeaderTabConfig = { const tabConfig: DynamicHeaderTabConfig = {
@@ -65,6 +69,7 @@ export function useDynamicHeaderTab() {
} }
// 如果启用了PWA状态恢复,监听PWA状态变化并同步到modelValue // 如果启用了PWA状态恢复,监听PWA状态变化并同步到modelValue
// 但只在非激活状态下响应,避免干扰页面激活时的状态
if (pwaTabState) { if (pwaTabState) {
watch(pwaTabState.activeTab, newTab => { watch(pwaTabState.activeTab, newTab => {
if (newTab && newTab !== config.modelValue.value) { if (newTab && newTab !== config.modelValue.value) {
@@ -152,7 +157,15 @@ export function useDynamicHeaderTab() {
// 处理页面激活时重新注册(支持keep-alive缓存的页面) // 处理页面激活时重新注册(支持keep-alive缓存的页面)
onActivated(() => { onActivated(() => {
// 页面激活时,优先使用当前页面的实际状态,而不是恢复的PWA状态
// 这样可以避免从后台切换回来时显示错误的标签页
nextTick(() => { nextTick(() => {
// 确保使用当前页面的实际modelValue,不受PWA状态恢复影响
tabConfig.modelValue = config.modelValue.value
// 同步当前状态到PWA存储,确保状态一致性
if (pwaTabState && config.modelValue.value) {
pwaTabState.activeTab.value = config.modelValue.value
}
doRegister() doRegister()
}) })
}) })
+1 -14
View File
@@ -48,7 +48,7 @@ export function useTabStateRestore(defaultTab?: string) {
} }
}) })
// 组件挂载时恢复状态 // 组件挂载时恢复状态(仅在首次加载时)
onMounted(() => { onMounted(() => {
// 先尝试恢复,如果没有保存的状态则使用默认值 // 先尝试恢复,如果没有保存的状态则使用默认值
if (!restoreTabState() && defaultTab) { if (!restoreTabState() && defaultTab) {
@@ -56,19 +56,6 @@ export function useTabStateRestore(defaultTab?: string) {
} }
}) })
// 监听全局恢复事件
const handleRestore = () => {
restoreTabState()
}
onMounted(() => {
window.addEventListener('pwa-state-restore', handleRestore)
})
onUnmounted(() => {
window.removeEventListener('pwa-state-restore', handleRestore)
})
return { return {
activeTab, activeTab,
saveTabState, saveTabState,
+9 -7
View File
@@ -149,23 +149,25 @@ class StateRestore {
// 页面显示时检查是否需要恢复状态 // 页面显示时检查是否需要恢复状态
document.addEventListener('visibilitychange', () => { document.addEventListener('visibilitychange', () => {
if (!document.hidden) { if (!document.hidden) {
this.checkAndRestore() // 只恢复路由状态,不自动恢复标签页状态
// 标签页状态由组件自己控制,避免干扰当前页面状态
this.checkAndRestoreRoute()
} }
}) })
// 页面加载完成后恢复状态 // 页面加载完成后恢复状态
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => this.checkAndRestore(), 100) setTimeout(() => this.checkAndRestoreRoute(), 100)
}) })
} else { } else {
setTimeout(() => this.checkAndRestore(), 100) setTimeout(() => this.checkAndRestoreRoute(), 100)
} }
} }
// 检查并恢复状态 // 检查并恢复路由状态(不恢复标签页状态)
private checkAndRestore() { private checkAndRestoreRoute() {
// 1. 恢复路由(如果当前路径与保存的不同) // 恢复路由(如果当前路径与保存的不同)
const savedRoute = this.route.restoreRoute() const savedRoute = this.route.restoreRoute()
if (savedRoute && savedRoute.path !== window.location.pathname) { if (savedRoute && savedRoute.path !== window.location.pathname) {
const fullPath = savedRoute.path + savedRoute.search + savedRoute.hash const fullPath = savedRoute.path + savedRoute.search + savedRoute.hash
@@ -173,7 +175,7 @@ class StateRestore {
window.history.replaceState(null, '', fullPath) window.history.replaceState(null, '', fullPath)
} }
// 2. 发送恢复事件,让组件自行处理标签页恢复 // 发送恢复事件,但标签页恢复由组件自己决定
window.dispatchEvent( window.dispatchEvent(
new CustomEvent('pwa-state-restore', { new CustomEvent('pwa-state-restore', {
detail: { detail: {