一个面向 UniApp 的 Pinia 持久化插件:pinia-plugin-uni-persist-next
在 Vue 3 + Pinia 项目中,store 默认只存在于内存里。页面刷新、App 重启或小程序重新进入后,状态都会回到初始值。
UniApp 项目通常需要同时兼容 H5、App 和小程序,直接依赖 localStorage 并不合适。因此,这个插件基于 UniApp 的 storage API,提供了一套 Pinia 状态持久化方案。
@rdeam/pinia-plugin-uni-persist-next 主要用于在 UniApp 项目中自动保存和恢复 Pinia store。
安装
perl
pnpm add @rdeam/pinia-plugin-uni-persist-next
基本使用
先在 Pinia 初始化时注册插件:
javascript
import { createPinia } from 'pinia';
import { createUniPersistPlugin } from '@rdeam/pinia-plugin-uni-persist-next';
const pinia = createPinia();
pinia.use(
createUniPersistPlugin({
keyPrefix: 'app_storage_',
}),
);
然后在需要持久化的 store 里开启 persist:
javascript
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null,
}),
persist: {
enabled: true,
strategies: [
{
key: 'user',
paths: ['token'],
},
],
},
});
上面这个例子只会持久化 token,不会保存整个 userInfo。
为什么需要 paths
不是所有状态都适合持久化。
比如用户 token、语言设置、主题设置,这类数据通常可以保存。
但列表数据、临时弹窗状态、接口返回的大对象,不一定适合长期放进 storage。
所以插件提供了 paths:
yaml
persist: {
enabled: true,
strategies: [
{
key: 'user',
paths: ['token'],
},
],
}
paths 目前只支持顶层字段。也就是说,['token'] 可以,['user.info.name'] 这种深层路径不是当前版本的能力。
多策略保存
一个 store 可以配置多个保存策略:
css
persist: {
enabled: true,
strategies: [
{
key: 'user_token',
paths: ['token'],
},
{
key: 'user_profile',
paths: ['userInfo'],
},
],
}
这适合把不同字段拆到不同 storage key 里。比如 token 和用户资料可以分开管理。
同步恢复,默认异步写入
插件恢复数据时使用 uni.getStorageSync,这样 store 初始化时就可以尽快拿到本地数据。
写入时默认使用 uni.setStorage:
yaml
persist: {
enabled: true,
async: true,
}
如果希望写入也使用同步 API,可以这样配置:
yaml
persist: {
enabled: true,
async: false,
}
也可以在单个策略上覆盖:
yaml
persist: {
enabled: true,
strategies: [
{
key: 'user',
paths: ['token'],
async: false,
},
],
}
恢复前后的钩子
插件提供了两个钩子:
javascript
persist: {
enabled: true,
beforeRestore(ctx) {
console.log('恢复前', ctx.store.$id);
},
afterRestore(ctx) {
console.log('恢复后', ctx.store.$id);
},
}
这两个钩子适合做日志、埋点,或者在恢复前后处理一些简单逻辑。
清理 storage
插件也提供了两个工具方法:
javascript
import { clearAll, clearStore } from '@rdeam/pinia-plugin-uni-persist-next';
clearStore('app_storage_user');
clearAll();
需要注意:clearAll() 调用的是 uni.clearStorageSync(),会清空当前应用的 storage,不只清理这个插件写入的数据。业务项目里使用时要谨慎。
数据序列化说明
storage 最终保存的是字符串,所以插件内部会做 JSON 序列化。
当前版本对以下数据做了处理:
Date:保存时会转成带标记的对象,恢复时再转回DateBigInt:保存时会转成字符串,避免JSON.stringify报错- 循环引用:保存时会使用占位字符串,避免序列化直接失败
这里需要说清楚:BigInt 当前恢复后是字符串,不是 bigint。如果业务强依赖 bigint 类型,需要在读取后自行转换,或者等待后续版本支持完整还原。
适合什么场景
这个插件比较适合这些场景:
- UniApp 项目使用 Pinia 管理状态
- 需要保存 token、用户偏好、简单配置
- 希望 store 初始化时自动恢复本地数据
- 不想在每个 store 里手写
uni.setStorage
不太适合这些场景:
- 需要保存大量列表数据
- 需要复杂的深层字段选择
- 需要加密、过期时间、版本迁移等高级能力
- 对 BigInt、Map、Set 等复杂类型有完整还原要求
这些能力可以在业务层处理,也可以作为插件后续版本的演进方向。
小结
@rdeam/pinia-plugin-uni-persist-next 不是一个复杂插件,它主要解决的是 UniApp 项目里 Pinia 状态持久化的基础问题:
- store 开启配置后自动保存
- 应用启动时自动恢复
- 支持 key 前缀
- 支持字段筛选
- 支持同步或异步写入
- 基于 UniApp storage API,适合多端项目
如果项目里只是想稳定保存 token、设置项、用户偏好这类轻量状态,它可以减少不少重复代码。对于更复杂的数据持久化需求,建议结合业务场景继续封装。