封装缓存组件 统一管理缓存设置 减少请求 优化逻辑
封装缓存函数
缓存的键和时间也可以放在一起,更好统一管理。
// 缓存键前缀
const PREFIX = 'diamond_'// 缓存时间配置(毫秒)
const CACHE_TIME = {SHORT: 5 * 60 * 1000, // 5分钟MEDIUM: 30 * 60 * 1000, // 30分钟LONG: 24 * 60 * 60 * 1000, // 1天WEEK: 7 * 24 * 60 * 60 * 1000 // 1周
}// 缓存版本号,用于缓存更新
const CACHE_VERSION = '1.0.0'export const cache = {// 设置缓存 默认过期时间30分钟set(key, value, expire = CACHE_TIME.MEDIUM) {const data = {value,expire: expire ? Date.now() + expire : null,version: CACHE_VERSION}try {localStorage.setItem(PREFIX + key, JSON.stringify(data))return true} catch (e) {// 如果存储失败(存储已满),清理过期缓存后重试if (e.name === 'QuotaExceededError') {this.clearExpired()try {localStorage.setItem(PREFIX + key, JSON.stringify(data))return true} catch (e) {console.error('Cache storage failed:', e)return false}}return false}},// 获取缓存get(key) {const data = localStorage.getItem(PREFIX + key)if (!data) return nulltry {const { value, expire, version } = JSON.parse(data)// 检查版本号和过期时间if (version !== CACHE_VERSION || (expire && Date.now() > expire)) {this.remove(key)return null}return value} catch {this.remove(key)return null}},// 移除缓存remove(key) {localStorage.removeItem(PREFIX + key)},// 清除所有缓存clear() {Object.keys(localStorage).forEach(key => {if (key.startsWith(PREFIX)) {localStorage.removeItem(key)}})},// 清除过期缓存clearExpired() {Object.keys(localStorage).forEach(key => {if (key.startsWith(PREFIX)) {try {const data = JSON.parse(localStorage.getItem(key))if (data.version !== CACHE_VERSION || (data.expire && Date.now() > data.expire)) {localStorage.removeItem(key)}} catch {localStorage.removeItem(key)}}})},// 获取缓存大小(字节)size() {let size = 0Object.keys(localStorage).forEach(key => {if (key.startsWith(PREFIX)) {size += localStorage.getItem(key).length * 2 // UTF-16 编码每个字符占2字节}})return size},// 检查缓存是否可用isAvailable() {try {const testKey = PREFIX + 'test'localStorage.setItem(testKey, 'test')localStorage.removeItem(testKey)return true} catch {return false}},// 获取所有缓存键keys() {return Object.keys(localStorage).filter(key => key.startsWith(PREFIX)).map(key => key.slice(PREFIX.length))},// 批量设置缓存setMany(items, expire = CACHE_TIME.MEDIUM) {return items.every(({ key, value }) => this.set(key, value, expire))},// 批量获取缓存getMany(keys) {return keys.map(key => ({ key, value: this.get(key) }))},// 批量删除缓存removeMany(keys) {keys.forEach(key => this.remove(key))}
}// 缓存键定义
export const CACHE_KEYS = {USER_INFO: 'user_info',DIAMOND_LIST: 'diamond_list',DIAMOND_DETAIL: 'diamond_detail_',FILTER_OPTIONS: 'filter_options',LANGUAGE: 'language',MENU_STATE: 'menu_state',THEME: 'theme',USER_PREFERENCES: 'user_preferences'
}// 缓存时间定义
export const CACHE_EXPIRES = {USER_INFO: CACHE_TIME.WEEK,DIAMOND_LIST: CACHE_TIME.SHORT,DIAMOND_DETAIL: CACHE_TIME.MEDIUM,FILTER_OPTIONS: CACHE_TIME.LONG,LANGUAGE: CACHE_TIME.LONG,MENU_STATE: CACHE_TIME.LONG,THEME: CACHE_TIME.LONG,USER_PREFERENCES: CACHE_TIME.LONG
}// 定期清理过期缓存(每小时)
if (typeof window !== 'undefined') {setInterval(() => {cache.clearExpired()}, 60 * 60 * 1000)
}export default cache
接口缓存
减少每次刷新或跳转进行数据请求,也可以进行二次封装减少代码量
import { cache, CACHE_KEYS, CACHE_EXPIRES } from '@/utils/cache'// 获取钻石列表
export function getDiamondPage(params) {// 生成缓存键const cacheKey = CACHE_KEYS.DIAMOND_LIST + JSON.stringify(params)// 尝试从缓存获取const cachedData = cache.get(cacheKey)if (cachedData) {return Promise.resolve(cachedData)}// 发起请求return request({url: '/admin-api/bs/diamond/page',method: 'post',data: params}).then(res => {if (res.code === 0) {// 设置缓存cache.set(cacheKey, res, CACHE_EXPIRES.DIAMOND_LIST)}return res})
}
配置缓存
// 获取配置信息
const getCurrentLanguage = () => {const cachedLang = cache.get(CACHE_KEYS.LANGUAGE)if (cachedLang) return cachedLangconst browserLang = navigator.language.toLowerCase()return browserLang.includes('zh') ? 'zh-CN' : 'en-US'
}
// 设置配置信息
cache.set(CACHE_KEYS.LANGUAGE, locale, CACHE_EXPIRES.LANGUAGE)