pinia插件在store创建时立即执行,于setup前注入初始状态;需直接赋值store.$state以确保响应性,配合$subscribe和storage事件实现持久化同步,并支持手动控制如flush、reload及migrate。

Pinia 插件本身没有独立的“生命周期钩子”,它的执行时机完全由 Pinia 的内部初始化流程决定。所谓“插件生命周期”,其实是插件函数在 store 创建不同阶段被调用的自然顺序——掌握这个顺序,就能精准控制状态注入的时机和行为。
插件函数在 store 实例创建时立即执行
Pinia 插件是一个函数,它会在每个 store 实例被 defineStore 创建后、setup 函数执行前 被调用一次。此时 store 尚未完成响应式代理,state 还是原始对象,正是注入初始状态的最佳窗口。
- 插件接收 store 实例作为唯一参数,可直接读写
store.$state - 若需从 localStorage 恢复状态,应在此处读取并赋值:
store.$state = JSON.parse(stored) || store.$state - 避免使用
Object.assign(store.$state, ...),它可能触发不必要的响应式更新
状态注入必须在响应式建立前完成
Pinia 的 state 在 setup 返回后才被转换为响应式 proxy。如果在 setup 内部或之后才覆盖 store.$state,会丢失响应性或导致数据不一致。
- 推荐做法:插件中直接赋值
store.$state = hydratedState - 不推荐:在
store.$onAction或store.$subscribe中尝试恢复初始状态(太晚了) - 可通过
store._isHydrated等自定义属性标记是否已注入,防止重复操作
利用 $subscribe 和 storage 事件实现后续同步
状态注入只是第一步。要保持持久化效果,还需监听变更并写入存储,同时响应其他标签页的修改。
-
store.$subscribe在每次 commit 后触发,适合做防抖写入(如 300ms 延迟localStorage.setItem) -
window.addEventListener('storage')可捕获同域下其他 tab 的 localStorage 变更,用于自动更新本页 state - 注意过滤自身触发的 storage 事件,避免无限循环(例如比对
event.key和当前 store key,并跳过本页写入源)
手动控制接口增强灵活性
生产环境常需主动干预持久化行为,比如登录后清空旧用户缓存、版本升级时迁移数据。
- 在插件中为 store 添加方法,如
store.$persist.flush()清空本地存储 - 提供
store.$persist.reload()强制从 storage 重新加载当前 state - 支持
migrate钩子,在恢复前对旧格式数据做兼容处理










