142 lines
4.2 KiB
JavaScript
142 lines
4.2 KiB
JavaScript
/**
|
||
* 骨架屏管理器
|
||
* 用于控制页面骨架屏的显示逻辑
|
||
*
|
||
* 逻辑说明:
|
||
* 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)
|
||
} else {
|
||
// 同一次应用启动,恢复已访问记录
|
||
const cachedVisitedPages = uni.getStorageSync('visitedPages')
|
||
if (cachedVisitedPages && Array.isArray(cachedVisitedPages)) {
|
||
this.visitedPages = new Set(cachedVisitedPages)
|
||
}
|
||
}
|
||
} catch (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)
|
||
return shouldShow
|
||
}
|
||
|
||
/**
|
||
* 标记页面已访问
|
||
* @param {string} pagePath - 页面路径
|
||
* @param {string} pageType - 页面类型参数(可选)
|
||
*/
|
||
markPageVisited(pagePath, pageType = '') {
|
||
const pageKey = this.generatePageKey(pagePath, pageType)
|
||
|
||
this.visitedPages.add(pageKey)
|
||
this.saveToCache()
|
||
}
|
||
|
||
/**
|
||
* 保存访问记录到缓存
|
||
*/
|
||
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 |