封装localStorage
在utils目录下新建storage.ts
ts
/**
* localStorage 封装工具
* 提供类型安全、带过期时间、异常捕获的本地存储操作
*/
/** 存储项的内部结构 */
interface StorageItem<T> {
/** 实际存储的值 */
value: T;
/** 过期时间戳(毫秒),null 表示永不过期 */
expires: number | null;
}
/**
* 设置存储值
* @param key 存储键名
* @param value 要存储的值(支持对象、数组、数字、布尔值等可序列化类型)
* @param ttl 可选,过期时长(毫秒),不传则永不过期
* @returns 是否设置成功
* @example
* setItem('user', { name: '张三', age: 18 });
* setItem('token', 'abc123', 1000 * 60 * 30); // 30 分钟后过期
*/
export function setItem<T>(key: string, value: T, ttl?: number): boolean {
try {
const item: StorageItem<T> = {
value,
expires: typeof ttl === "number" ? Date.now() + ttl : null,
};
localStorage.setItem(key, JSON.stringify(item));
return true;
} catch (error) {
console.error(`[storage] 设置 "${key}" 失败:`, error);
return false;
}
}
/**
* 获取存储值
* 若已过期则自动删除并返回 null
* @param key 存储键名
* @returns 存储的值,不存在或已过期时返回 null
* @example
* const user = getItem<{ name: string; age: number }>('user');
* const token = getItem<string>('token');
*/
export function getItem<T>(key: string): T | null {
try {
const raw = localStorage.getItem(key);
if (raw === null) return null;
const item = JSON.parse(raw) as StorageItem<T>;
// 校验过期时间
if (item.expires !== null && Date.now() > item.expires) {
localStorage.removeItem(key);
return null;
}
return item.value;
} catch (error) {
console.error(`[storage] 读取 "${key}" 失败:`, error);
return null;
}
}
/**
* 删除单个存储值
* @param key 存储键名
* @example
* removeItem('token');
*/
export function removeItem(key: string): void {
try {
localStorage.removeItem(key);
} catch (error) {
console.error(`[storage] 删除 "${key}" 失败:`, error);
}
}
/**
* 清空所有存储值
* @example
* clear();
*/
export function clear(): void {
try {
localStorage.clear();
} catch (error) {
console.error("[storage] 清空存储失败:", error);
}
}