pinia-plugin-persistedstate详解与Vue3使用示例
文章目录一、核心原理二、核心配置项完整三、Vue3 完整使用步骤1. 安装依赖2. 全局注册插件main.ts/main.js3. Store 中启用持久化两种风格1Option Store 风格选项式2Setup Store 风格组合式推荐 Vue34. 多策略持久化进阶5. 组件中使用四、常见场景与最佳实践五、常见问题pinia-plugin-persistedstate是 Pinia 官方生态中最主流的状态持久化插件核心作用是将 Pinia 的状态自动同步到本地存储如 localStorage/sessionStorage页面刷新后状态不丢失解决内存状态易重置的痛点。它配置极简、支持细粒度控制、兼容 Vue3 与 Pinia 全版本是 Vue3 项目状态持久化的首选方案。一、核心原理插件通过Pinia 的插件机制全局注册监听所有 Store 的状态变更。状态更新时自动序列化并写入指定存储介质默认 localStorage。页面初始化时自动反序列化读取存储数据覆盖到对应 Store 的 state。支持全局配置 单个 Store 配置优先级Store 配置 全局配置。二、核心配置项完整persist支持布尔值简单开启或对象精细配置完整配置如下配置项类型默认值说明enabledbooleantrue是否启用持久化keystringStore ID存储在 localStorage 中的键名建议自定义避免冲突storageStoragelocalStorage存储介质localStorage/sessionStorage/自定义存储pathsstring[]undefined仅持久化指定字段路径数组如[user.token, theme]serializerobjectJSON自定义序列化/反序列化{ serialize, deserialize }beforeRestore() void-状态恢复前钩子afterRestore() void-状态恢复后钩子strategiesarray-多策略配置不同字段用不同存储三、Vue3 完整使用步骤1. 安装依赖# npmnpminstallpinia pinia-plugin-persistedstate# yarnyarnaddpinia pinia-plugin-persistedstate# pnpmpnpmaddpinia pinia-plugin-persistedstate2. 全局注册插件main.ts/main.jsimport{createApp}fromvueimport{createPinia}frompinia// 引入持久化插件importpiniaPluginPersistedstatefrompinia-plugin-persistedstateimportAppfrom./App.vueconstappcreateApp(App)constpiniacreatePinia()// 注册插件全局生效pinia.use(piniaPluginPersistedstate)app.use(pinia)app.mount(#app)3. Store 中启用持久化两种风格1Option Store 风格选项式最简用法全部字段持久化到 localStorage// src/stores/counter.tsimport{defineStore}frompiniaexportconstuseCounterStoredefineStore(counter,{state:()({count:0,isLoading:false}),actions:{increment(){this.count}},// ✅ 开启持久化默认配置persist:true})精细配置推荐生产环境// src/stores/user.tsimport{defineStore}frompiniaexportconstuseUserStoredefineStore(user,{state:()({token:,userInfo:{id:,name:,avatar:},tempData:null// 不需要持久化}),actions:{setToken(token:string){this.tokentoken},logout(){this.tokenthis.userInfo{id:,name:,avatar:}// 清除本地存储localStorage.removeItem(app-user-store)}},// ✅ 自定义持久化配置persist:{key:app-user-store,// 自定义存储键storage:localStorage,// 存储介质paths:[token,userInfo],// 仅持久化指定字段// 自定义序列化处理 Date 等特殊类型serializer:{serialize:(value)JSON.stringify(value),deserialize:(value)JSON.parse(value)},// 恢复钩子afterRestore:(ctx){console.log(用户状态已恢复,ctx.store.$state)}}})2Setup Store 风格组合式推荐 Vue3// src/stores/setting.tsimport{defineStore}frompiniaimport{ref,reactive}fromvueexportconstuseSettingStoredefineStore(setting,(){// 状态constthemeref(light)constlanguageref(zh-CN)constcollapsedref(false)// 动作constsetTheme(val:string){theme.valueval}// ✅ 持久化配置第三个参数return{theme,language,collapsed,setTheme}},{persist:{key:app-setting,storage:sessionStorage,// 会话存储关闭标签页清空paths:[theme,language]// 不持久化 collapsed}})4. 多策略持久化进阶不同字段使用不同存储介质persist:{strategies:[// token 长期保存到 localStorage{key:auth-token,storage:localStorage,paths:[token]},// 主题仅会话保存到 sessionStorage{key:ui-theme,storage:sessionStorage,paths:[theme]}]}5. 组件中使用script setup langts import { useCounterStore } from /stores/counter import { useUserStore } from /stores/user import { storeToRefs } from pinia // 保持解构响应式 const counterStore useCounterStore() const userStore useUserStore() // 解构状态必须用 storeToRefs const { count } storeToRefs(counterStore) const { token, userInfo } storeToRefs(userStore) // 调用方法 const add () counterStore.increment() /script template div h2计数{{ count }}/h2 button clickadd1/button div v-iftoken p用户名{{ userInfo.name }}/p button clickuserStore.logout退出登录/button /div div v-else未登录/div /div /template四、常见场景与最佳实践只持久化必要字段用paths过滤减少存储体积。敏感信息处理token 等可持久化临时数据不要持久化。存储介质选择localStorage长期保存关闭浏览器仍在sessionStorage会话保存标签页关闭即清空清除持久化登出时用localStorage.removeItem(key)或store.$reset()。TypeScript 支持完美兼容无需额外配置。五、常见问题刷新后状态仍丢失检查persist是否开启、paths路径是否正确、存储键是否冲突。特殊类型Date/RegExp无法存储自定义serializer序列化。SSR 兼容需判断环境避免服务端访问window对象。