pinia 暗黑模式持久化需三步:状态存 pinia、切换时写 localstorage、初始化时读 localstorage 并同步;主题 store 中 darkmode 不设默认值,由 localstorage 读取决定;setdarkmode action 同步更新 store 与 localstorage,并操作 document.documentelement.classlist;'auto' 模式需监听系统偏好变化;多 store 场景推荐使用 pinia-plugin-persistedstate 等插件统一处理。

状态定义与存储位置
在主题 store(如 src/stores/app.ts)中定义 darkMode 字段,类型为 ThemeEnum(比如 'light' | 'dark' | 'auto'),初始值可设为 undefined 或根据系统偏好推导。关键不是“默认亮色”,而是留空让初始化逻辑决定:
- state 中不硬编码初始值,避免覆盖用户上次选择
- 用
localStorage.getItem(APP_DARK_MODE_KEY)在 store 初始化时读取真实偏好 - 读取结果优先用于设置
this.darkMode,再触发 DOM class 更新
切换动作与 localStorage 同步
提供一个 setDarkMode action,接收新主题值,并同时更新 store 状态和 localStorage:
- 执行
this.darkMode = mode触发响应式更新 - 立即调用
localStorage.setItem(APP_DARK_MODE_KEY, mode) - 额外建议:同步修改
元素的 class,例如document.documentElement.classList.toggle('dark', mode === 'dark'),确保 CSS 变量或 Tailwind 的dark:变体生效
自动适配系统偏好(可选增强)
当用户设为 'auto' 时,需监听系统主题变化:
- 用
window.matchMedia('(prefers-color-scheme: dark)')获取当前系统模式 - 在 store 初始化后注册
mediaQuery.addEventListener('change', ...) - 回调中判断是否应更新 darkMode(仅当当前为 'auto' 且系统模式已变)
- 注意:该监听器需在 store 卸载时移除,避免内存泄漏
避免手动重复写持久化逻辑
如果项目中多个 store 都需要持久化(如用户配置、布局设置等),不推荐每个都手写 localStorage 操作。可考虑:
- 封装一个
usePersistentStore工具函数,统一处理读/写/监听 - 在 uni-app 等跨平台场景,使用 pinia-plugin-persist-uni,它自动识别 H5 / 小程序 / App 平台并调用对应 API
- 对纯 Web 项目,pinia-plugin-persistedstate 是成熟选择,支持自定义 key、storage 和序列化方式










