caiyunyi/utils/skeletonManager.js
ylj20011123 781ceb7ab0 update
2025-09-05 18:37:20 +08:00

146 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 骨架屏管理器
* 用于控制页面骨架屏的显示逻辑
*
* 逻辑说明:
* 1. 首次进入小程序时,每个页面第一次访问都显示骨架屏
* 2. 对于带pageType参数的页面每个不同的pageType都算作一次新页面访问
* 3. 后续访问相同页面相同pageType不显示骨架屏
*/
class SkeletonManager {
constructor() {
this.visitedPages = new Set() // 存储已访问的页面标识
this.currentAppSession = null // 当前小程序会话ID
this.init()
}
/**
* 初始化,从缓存中恢复已访问页面记录
*/
init() {
try {
// 检查是否是新的小程序启动(应用级生命周期)
const appLaunchTime = getApp().globalData?.appLaunchTime || Date.now()
const lastAppLaunchTime = uni.getStorageSync('lastAppLaunchTime')
if (!lastAppLaunchTime || lastAppLaunchTime !== appLaunchTime) {
// 新的应用启动,清空所有已访问记录
this.visitedPages = new Set()
uni.removeStorageSync('visitedPages')
uni.setStorageSync('lastAppLaunchTime', appLaunchTime)
console.log('骨架屏管理器: 检测到新的小程序启动,重置访问记录')
} else {
// 同一次应用启动,恢复已访问记录
const cachedVisitedPages = uni.getStorageSync('visitedPages')
if (cachedVisitedPages && Array.isArray(cachedVisitedPages)) {
this.visitedPages = new Set(cachedVisitedPages)
console.log('骨架屏管理器: 恢复已访问记录', cachedVisitedPages)
}
}
} catch (error) {
console.warn('骨架屏管理器初始化失败:', error)
this.visitedPages = new Set()
}
}
/**
* 生成页面标识
* @param {string} pagePath - 页面路径
* @param {string} pageType - 页面类型参数(可选)
* @returns {string} 页面唯一标识
*/
generatePageKey(pagePath, pageType = '') {
if (pageType) {
return `${pagePath}?pageType=${pageType}`
}
return pagePath
}
/**
* 检查是否应该显示骨架屏
* @param {string} pagePath - 页面路径
* @param {string} pageType - 页面类型参数(可选)
* @returns {boolean} 是否显示骨架屏
*/
shouldShowSkeleton(pagePath, pageType = '') {
const pageKey = this.generatePageKey(pagePath, pageType)
const shouldShow = !this.visitedPages.has(pageKey)
console.log(`骨架屏检查 ${pageKey}: ${shouldShow ? '需要显示' : '已访问过'}`,
`当前已访问页面:`, Array.from(this.visitedPages))
return shouldShow
}
/**
* 标记页面已访问
* @param {string} pagePath - 页面路径
* @param {string} pageType - 页面类型参数(可选)
*/
markPageVisited(pagePath, pageType = '') {
const pageKey = this.generatePageKey(pagePath, pageType)
this.visitedPages.add(pageKey)
this.saveToCache()
console.log(`骨架屏标记已访问: ${pageKey}`, `当前已访问页面:`, Array.from(this.visitedPages))
}
/**
* 保存访问记录到缓存
*/
saveToCache() {
try {
uni.setStorageSync('visitedPages', Array.from(this.visitedPages))
} catch (error) {
console.warn('保存骨架屏访问记录失败:', error)
}
}
/**
* 清除所有访问记录(用于重置状态,比如用户重新打开小程序)
*/
clearAllVisited() {
this.visitedPages.clear()
uni.removeStorageSync('visitedPages')
}
/**
* 获取页面骨架屏控制状态
* 返回一个包含状态和控制方法的对象
* @param {string} pagePath - 页面路径
* @param {string} pageType - 页面类型参数(可选)
* @returns {object} 控制状态对象
*/
getPageSkeletonControl(pagePath, pageType = '') {
const shouldShow = this.shouldShowSkeleton(pagePath, pageType)
return {
// 是否显示骨架屏
showSkeleton: shouldShow,
// 是否显示内容
showContent: !shouldShow,
// 标记页面已访问的方法
markVisited: () => {
this.markPageVisited(pagePath, pageType)
},
// 手动控制显示内容的方法(用于异步加载完成后)
showContentAfterLoading: (delay = 500) => {
return new Promise((resolve) => {
setTimeout(() => {
this.markPageVisited(pagePath, pageType)
resolve(true)
}, delay)
})
}
}
}
}
// 创建全局单例
const skeletonManager = new SkeletonManager()
// 导出工厂函数,用于在页面中快速获取控制状态
export function useSkeletonControl(pagePath, pageType = '') {
return skeletonManager.getPageSkeletonControl(pagePath, pageType)
}
// 导出管理器实例(用于高级操作)
export default skeletonManager