将页面缓存存储到 IndexedDB 是一个常见的方式,可以用来离线存储页面数据、提升加载速度。以下是实现步骤和代码示例:
实现步骤
-
创建 IndexedDB 数据库
使用Dexie.js
或原生IndexedDB
API 创建数据库和存储表。 -
存储页面缓存
将页面相关的内容(如 HTML、CSS、JSON 数据等)以键值对形式存储到数据库中。 -
读取页面缓存
页面加载时检查数据库是否有缓存数据,如果有,则优先使用缓存数据。 -
更新页面缓存
每次从服务端获取新数据后,更新 IndexedDB 中的缓存。
代码示例
1. 创建数据库 (db.js
)
使用 Dexie.js
创建数据库,方便管理。
import Dexie from 'dexie';// 创建数据库实例
const db = new Dexie("PageCacheDB");// 定义表结构
db.version(1).stores({pageCaches: "url,data,timestamp" // url 是主键,data 存储页面内容,timestamp 用于记录缓存时间
});export default db;
2. 编写缓存管理逻辑 (cacheService.js
)
封装一组方法,用于存储、读取和更新缓存。
import db from './db';// 存储页面缓存
export const savePageCache = async (url, data) => {try {await db.pageCaches.put({url, // 唯一键data, // 页面内容(如 HTML 或 JSON)timestamp: Date.now() // 缓存时间});console.log(`缓存已存储: ${url}`);} catch (error) {console.error("存储缓存失败:", error);}
};// 获取页面缓存
export const getPageCache = async (url) => {try {const cache = await db.pageCaches.get(url);if (cache) {console.log(`缓存命中: ${url}`);return cache.data;} else {console.log(`缓存未命中: ${url}`);return null;}} catch (error) {console.error("读取缓存失败:", error);return null;}
};// 清理过期缓存(可选)
export const clearOldCaches = async (maxAge) => {try {const now = Date.now();const allCaches = await db.pageCaches.toArray();for (const cache of allCaches) {if (now - cache.timestamp > maxAge) {await db.pageCaches.delete(cache.url);console.log(`已清理过期缓存: ${cache.url}`);}}} catch (error) {console.error("清理缓存失败:", error);}
};
3. 使用缓存逻辑 (usePageCache.js
)
封装一个 React Hook,用于在组件中自动管理页面缓存。
import { useEffect, useState } from 'react';
import { savePageCache, getPageCache } from './cacheService';const usePageCache = (url, fetchData) => {const [data, setData] = useState(null);const [loading, setLoading] = useState(true);useEffect(() => {const fetchAndCache = async () => {setLoading(true);// 尝试从缓存中读取const cachedData = await getPageCache(url);if (cachedData) {setData(cachedData);setLoading(false);}// 获取最新数据并更新缓存const freshData = await fetchData();setData(freshData);savePageCache(url, freshData);setLoading(false);};fetchAndCache();}, [url, fetchData]);return { data, loading };
};export default usePageCache;
4. 使用示例 (App.js
)
在组件中使用缓存管理逻辑。
import React from 'react';
import usePageCache from './usePageCache';const App = () => {// 数据获取函数const fetchData = async () => {const response = await fetch("https://api.example.com/data");return response.json();};// 使用缓存 Hookconst { data, loading } = usePageCache("https://api.example.com/data", fetchData);if (loading) {return <div>加载中...</div>;}return (<div><h1>页面缓存示例</h1><pre>{JSON.stringify(data, null, 2)}</pre></div>);
};export default App;
附加功能
-
缓存过期策略
- 在
clearOldCaches
方法中设置缓存有效期,例如 7 天。 - 在
usePageCache
中检查timestamp
,决定是否更新缓存。
- 在
-
缓存清理按钮
- 提供一个按钮,用于清理所有缓存。
const clearCache = async () => {await db.pageCaches.clear();console.log("所有缓存已清除");
};
总结
以上代码实现了:
- 使用 IndexedDB 存储页面数据缓存。
- 从缓存读取数据优先,缺失时再获取最新数据。
- 自动更新缓存和处理过期策略。
你可以根据需求扩展功能,如添加缓存大小限制、分区管理等。