一个用于 UniApp 项目的 Pinia 持久化插件

一个面向 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:保存时会转成带标记的对象,恢复时再转回 Date
  • BigInt:保存时会转成字符串,避免 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、设置项、用户偏好这类轻量状态,它可以减少不少重复代码。对于更复杂的数据持久化需求,建议结合业务场景继续封装。

相关推荐
小徐_233332 分钟前
Wot UI 2.2.0 发布:Button 新增 subtle,VideoPreview 预览体验继续增强
前端·微信小程序·uni-app
山河木马2 小时前
矩阵专题3-怎么创建投影矩阵(uProjectionMatrix)
javascript·webgl·计算机图形学
天蓝色的鱼鱼3 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷4 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷4 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜4 小时前
Spring Boot 核心知识点总结
前端
lichenyang4534 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕4 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js