localstorage 是前端持久化层的关键组件,需通过分层封装、结构化元数据、容错降级和生命周期协同实现可维护、可扩展、具备容错能力的数据管理。

localStorage 本身不是架构,但它可以成为前端持久化层的关键组件。合理的设计模式能让它从“随便存个字符串”升级为可维护、可扩展、具备容错能力的数据管理层。
分层封装:抽象出 StorageService
避免在业务代码中直接调用 localStorage.setItem 或 getItem。应封装成统一的存储服务,集中处理序列化、异常、命名前缀和基础校验。
- 所有键名自动添加应用前缀,如 "health-v2_userPrefs",防止跨模块冲突
- 写入时强制 JSON.stringify,读取时自动 JSON.parse 并捕获解析错误
- 对 null、undefined、空字符串做标准化返回(例如默认返回 {} 或 [])
- 暴露 clearByPrefix 方法,便于按模块清理,而不是盲目调用 clear()
结构化 + 元数据:让数据自带上下文
单纯存一个对象不够健壮。建议在值中嵌入元信息,为后续演进留余地。
- 添加 version 字段,如 { version: "1.2", data: { theme: "dark" } },便于版本迁移时识别旧结构
- 加入 savedAt 时间戳,支持业务层判断是否过期(比如草稿保留7天)
- 敏感字段(如 token)可附加 expiresAt,读取时主动校验有效性
- 避免把多个不相关字段拼进同一个 key,按语义拆分:如 "auth_token"、"auth_user"、"auth_expires"
容错与降级:不假设 localStorage 总是可用
浏览器可能禁用 storage、触发配额错误、或处于无痕模式。生产环境必须兜底。
- 所有 set/get 操作都包裹 try...catch,捕获 QuotaExceededError 和 SecurityError
- 当 localStorage 不可用时,优雅退回到内存缓存(Map 或全局对象),保障功能不中断
- 提供手动导出/导入接口,让用户能备份关键数据为 JSON 文件,实现用户侧持久化
- 监听 storage 事件,在同域其他标签页变更时同步状态(注意:本页修改不会触发自身事件)
生命周期协同:配合业务状态流转
localStorage 的“永久”是静态的,但业务数据常有动态生命周期。需由上层逻辑驱动清理与更新。
- 登录成功后写入 auth_token 和 user_profile;登出时明确 remove 这两个 key
- 表单页面离开前自动保存草稿到 "form-draft-contact-20260624" 类键,带时间戳便于清理
- 启动时扫描以 "draft_" 开头的键,删除超过 3 天未更新的条目
- 主题切换时只更新 "ui_theme",不波及其他配置,保持各维度正交











