Skip to content

本地存储 (Local Storage)

@pt/utils/modules/storage 提供了带前缀、过期时间的本地存储封装。

Storage 类

Storage 类提供了对浏览器 localStorage 和 sessionStorage 的增强封装,支持前缀管理、过期时间控制和类型安全。

基本用法

typescript
import { Storage, createLocalStorage, createSessionStorage } from '@pt/utils/modules/storage';

// 创建本地存储实例
const storage = createLocalStorage('app:');

// 设置数据(可选过期时间)
storage.set('user', { name: 'John' }, 24 * 60 * 60 * 1000); // 24小时后过期

// 获取数据
const user = storage.get('user');

// 移除数据
storage.remove('user');

// 清除所有数据
storage.clear();

// 使用会话存储
const sessionStorage = createSessionStorage('app:');

主要特性

1. 前缀管理

可为键名添加前缀,方便多应用或多模块管理,避免键名冲突。

typescript
// 创建应用专用存储
const userStorage = createLocalStorage('user:');
const appStorage = createLocalStorage('app:');
const cacheStorage = createLocalStorage('cache:');

// 实际存储的键名会自动添加前缀
userStorage.set('profile', data); // 存储为 'user:profile'
appStorage.set('config', data);   // 存储为 'app:config'
cacheStorage.set('temp', data);   // 存储为 'cache:temp'

2. 过期时间

支持设置数据的过期时间,过期后自动失效。

typescript
const storage = createLocalStorage('app:');

// 设置1小时后过期
storage.set('token', 'abc123', 60 * 60 * 1000);

// 设置7天后过期
storage.set('userInfo', userData, 7 * 24 * 60 * 60 * 1000);

// 永久存储(不设置过期时间)
storage.set('theme', 'dark');

3. 类型安全

支持 TypeScript 泛型,提供完整的类型推断和类型检查。

typescript
interface UserProfile {
  name: string;
  role: string;
  email: string;
}

const storage = createLocalStorage('user:');

// 存储时指定类型
storage.set<UserProfile>('profile', {
  name: 'Alice',
  role: 'admin',
  email: 'alice@example.com'
});

// 获取时自动推断类型
const profile = storage.get<UserProfile>('profile');
if (profile) {
  console.log(profile.name);  // TypeScript 知道这是 string
  console.log(profile.role);  // TypeScript 知道这是 string
}

4. 安全清除

可选择性地只清除特定前缀的数据,不影响其他数据。

typescript
const userStorage = createLocalStorage('user:');
const appStorage = createLocalStorage('app:');

userStorage.set('token', 'abc');
appStorage.set('config', { theme: 'dark' });

// 只清除用户相关数据,不影响应用配置
userStorage.clear(); // 只清除以 'user:' 开头的数据

API 参考

createLocalStorage(prefix?: string)

创建一个 localStorage 实例。

参数:

  • prefix (可选): 键名前缀,默认为空字符串

返回:

  • Storage 实例

createSessionStorage(prefix?: string)

创建一个 sessionStorage 实例。

参数:

  • prefix (可选): 键名前缀,默认为空字符串

返回:

  • Storage 实例

storage.set(key: string, value: T, expire?: number)

存储数据。

参数:

  • key: 存储键名
  • value: 要存储的值(会自动序列化)
  • expire (可选): 过期时间(毫秒)

storage.get<T>(key: string): T | null

获取数据。

参数:

  • key: 存储键名

返回:

  • 存储的值(自动反序列化)或 null(如果不存在或已过期)

storage.remove(key: string)

移除指定的数据。

storage.clear()

清除所有带有当前前缀的数据。

完整示例

typescript
import { createLocalStorage } from '@pt/utils/modules/storage';

// 定义用户数据类型
interface User {
  id: number;
  name: string;
  email: string;
  role: 'admin' | 'user';
}

// 创建用户存储实例
const userStorage = createLocalStorage('user:');

// 存储用户信息,7天后过期
const user: User = {
  id: 1,
  name: 'Alice',
  email: 'alice@example.com',
  role: 'admin'
};

userStorage.set('profile', user, 7 * 24 * 60 * 60 * 1000);

// 获取用户信息
const profile = userStorage.get<User>('profile');
if (profile) {
  console.log(`Welcome, ${profile.name}!`);
  console.log(`Role: ${profile.role}`);
}

// 用户登出时清除数据
function logout() {
  userStorage.clear();
  console.log('User data cleared');
}

使用场景

1. 用户信息存储

typescript
const userStorage = createLocalStorage('user:');

// 登录后存储用户信息
function onLogin(user: User) {
  userStorage.set('profile', user, 24 * 60 * 60 * 1000); // 24小时
  userStorage.set('token', user.token, 2 * 60 * 60 * 1000); // 2小时
}

// 获取当前用户
function getCurrentUser(): User | null {
  return userStorage.get<User>('profile');
}

// 登出清除数据
function onLogout() {
  userStorage.clear();
}

2. 应用配置存储

typescript
const configStorage = createLocalStorage('config:');

interface AppConfig {
  theme: 'light' | 'dark';
  language: string;
  fontSize: number;
}

// 保存配置(永久存储)
function saveConfig(config: AppConfig) {
  configStorage.set('app', config);
}

// 加载配置
function loadConfig(): AppConfig {
  return configStorage.get<AppConfig>('app') || {
    theme: 'light',
    language: 'zh-CN',
    fontSize: 14
  };
}

3. 缓存管理

typescript
const cacheStorage = createLocalStorage('cache:');

async function fetchWithCache<T>(key: string, fetcher: () => Promise<T>, ttl: number = 5 * 60 * 1000): Promise<T> {
  // 检查缓存
  const cached = cacheStorage.get<T>(key);
  if (cached) return cached;
  
  // 获取新数据
  const data = await fetcher();
  
  // 缓存数据
  cacheStorage.set(key, data, ttl);
  
  return data;
}

最佳实践

  1. 使用前缀隔离数据:为不同模块使用不同前缀
  2. 设置合理过期时间:避免敏感数据长期存储
  3. 类型安全:使用 TypeScript 泛型确保类型安全
  4. 错误处理:处理存储配额超限等异常情况
typescript
// ✅ 推荐:使用前缀和过期时间
const userStorage = createLocalStorage('user:');
userStorage.set('session', sessionData, 2 * 60 * 60 * 1000);

// ✅ 推荐:使用类型
interface UserData {
  id: number;
  name: string;
}
const user = userStorage.get<UserData>('profile');

// ❌ 不推荐:不使用前缀
const storage = createLocalStorage();
storage.set('data', value); // 可能与其他模块冲突

Released under the MIT License.