UniApp 项目 Pinia 持久化插件使用指南

作者:技术拾光

时间:2026-06-12

浏览:98

一个面向 UniApp 的 Pinia 持久化插件:pinia-plugin-uni-persist-next 在 Vue 3 + Pinia 的项目里,store 默认就是个内存里的“临时工”——页面一刷新、App 一重启、或者小程序重新进来,所有状态立刻打回原形,辛苦存的数据说没就没。 可问题是

文章目录

一个面向 UniApp 的 Pinia 持久化插件:pinia-plugin-uni-persist-next

在 Vue 3 + Pinia 的项目里,store 默认就是个内存里的“临时工”——页面一刷新、App 一重启、或者小程序重新进来,所有状态立刻打回原形,辛苦存的数据说没就没。

UniApp 项目 Pinia 持久化插件使用指南

可问题是,UniApp 项目经常要同时跑在 H5、App 和小程序上,直接拿 localStorage 来撑显然不合适。所以这个插件干脆直接基于 UniApp 自带的 storage API 来做了一套 Pinia 持久化方案,为的就是解决这种“跨端”环境下最头疼的状态保存问题。

简单说,@rdeam/pinia-plugin-uni-persist-next 就是帮你自动把 Pinia 里的 store 写进 UniApp 的 storage,再在启动时自动拉回来,省得自己一遍遍写 uni.setStorage 或者 uni.getStorage。

安装

pnpm add @rdeam/pinia-plugin-uni-persist-next

基本使用

用之前,先得把插件注册到 Pinia 实例里,给 store 装上一个“持久化引擎”:

import { createPinia } from 'pinia';
import { createUniPersistPlugin } from '@rdeam/pinia-plugin-uni-persist-next';const pinia = createPinia();pinia.use(
  createUniPersistPlugin({
    keyPrefix: 'app_storage_',
  }),
);

接下来,在需要持久化的 store 里加上 persist 配置,像这样:

import { defineStore } from 'pinia';export const useUserStore = defineStore('user', {
  state: () => ({
    token: '',
    userInfo: null,
  }),
  persist: {
    enabled: true,
    strategies: [
      {
        key: 'user',
        paths: ['token'],
      },
    ],
  },
});

这个例子里的效果是——只持久化 token 字段,userInfo 那堆对象不会被写入 storage。对比起以前手动读写 storage 的重复劳动,这个配置式的方法清爽太多。

为什么需要 paths

这里面为什么要提 paths?因为不是所有状态都适合一股脑塞进 storage。

比如用户的 token、语言设置、主题配置——这些确实该存着。但要是把列表数据、临时弹窗状态、甚至接口返回的大对象也往里扔,不仅浪费空间,还可能带来性能损耗。

所以插件提供了 paths 让开发者精确控制要持久化的字段:

persist: {
  enabled: true,
  strategies: [
    {
      key: 'user',
      paths: ['token'],
    },
  ],
}

不过得注意一下,paths 现在只支持顶层字段。也就是说写 ['token'] 完全 OK,但像 ['user.info.name'] 这种深层路径目前还不太行——这不是这个版本的能力范围。

多策略保存

一个 store 还可以配置多个保存策略,把不同字段拆到不同的 storage key 里。比如:

persist: {
  enabled: true,
  strategies: [
    {
      key: 'user_token',
      paths: ['token'],
    },
    {
      key: 'user_profile',
      paths: ['userInfo'],
    },
  ],
}

这样一来,token 和用户资料就能分开放、分开管,比全都挤在一个 key 里更加清晰。

同步恢复,默认异步写入

对于恢复这个环节,插件用的是 uni.getStorageSync,好处是在 store 初始化的时候能尽可能快地拿到本地数据,不会因为异步等待而阻塞整个流程。

写入的时候,默认走的是异步 API uni.setStorage:

persist: {
  enabled: true,
  async: true,
}

当然也支持改成同步写入,配置起来也很简单:

persist: {
  enabled: true,
  async: false,
}

甚至还可以在单个策略上单独控制,不需要全局调:

persist: {
  enabled: true,
  strategies: [
    {
      key: 'user',
      paths: ['token'],
      async: false,
    },
  ],
}

恢复前后的钩子

插件提供了两个生命周期钩子,beforeRestore 和 afterRestore:

persist: {
  enabled: true,
  beforeRestore(ctx) {
    console.log('恢复前', ctx.store.$id);
  },
  afterRestore(ctx) {
    console.log('恢复后', ctx.store.$id);
  },
}

这两个钩子比较适合做日志、埋点,或者在恢复前后处理一些简单的逻辑,比如在恢复后触发一次数据同步之类的。不过要记住,钩子里尽量别做太重的操作,毕竟持久化恢复本身涉及同步读写,一旦卡住会影响整体体验。

清理 storage

插件还内置了两个工具方法:

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 在初始化时自动恢复到内存里,不用自己调 storage API
  • 不想在每个 store 里重复手写 uni.setStorage 和 uni.getStorage

不太适合的情况也很清楚:

  • 需要保存大量列表数据,比如上千条的表格或日志
  • 需要复杂的深层字段选择,比如 a.b.c.d 这种嵌套路径
  • 需要加密、过期时间、版本迁移等高级持久化能力
  • 对 BigInt、Map、Set 等复杂类型有完整的“存什么恢复什么”的要求

这些更复杂的需求,要么自己在业务层做封装,要么等这个插件后续版本慢慢补上。

小结

@rdeam/pinia-plugin-uni-persist-next 不是一个铺得很开的复杂插件,它核心解决的是 UniApp 项目里 Pinia 状态持久化的基础问题:

  • store 开启配置后自动保存
  • 应用启动时自动恢复到 store
  • 支持自定义 key 前缀
  • 支持按字段筛选,不一股脑全存
  • 支持同步或异步写入策略
  • 基于 UniApp 自带的 storage API,能适配多端

对于大部分只需要稳定保存 token、设置项、用户偏好这类轻量状态的场景,这个插件确实可以减少不少重复代码。而更复杂的数据持久化需求,建议结合你的业务情况继续在它的基础上做二次封装。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章