Pinia持久化插件 pinia-plugin-persistedstate 的基本使用

前言

在Vue项目开发过程中,状态管理是至关重要的环节。随着Pinia的推出,它凭借更简洁直观的API,逐渐成为Vuex的有力替代品。为了进一步简化本地存储的管理,pinia-plugin-persistedstate 插件应运而生,它能够帮助开发者轻松实现状态的持久化。

本文将详细介绍如何使用该插件,并解决在跨项目登录时由于数据格式不一致导致的问题。

安装插件

在项目的根目录下运行以下命令以安装插件:

ts 复制代码
npm i pinia-plugin-persistedstate

随后,在main.ts文件中引入并配置插件:

ts 复制代码
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

完成以上步骤后,Pinia便具备了持久化功能。

基本使用

假设我们需要管理用户信息userInfo,并将其持久化到本地存储中,那么就可以这样实现:

ts 复制代码
import { defineStore } from 'pinia';

export const useUserInfoStore = defineStore('userInfo', {
    state: () => ({
        userInfo: null as any
    }),
    persist: true,
    actions: {
        setUserInfo(info: any) {
            this.userInfo = info;
        }
    }
});

按照上述配置,用户信息将自动持久化到本地存储中。

仅持久化对象中的特定字段

在实际应用中,开发者可能会面临跨项目登录时出现的兼容性问题。具体场景为:用户在项目A完成登录操作后,随即打开项目B。由于Token的复用机制,项目B会自动完成登录流程。然而,在尝试获取用户信息userInfo时,由于不同项目对数据格式的定义存在差异,导致项目B无法准确获取用户的ID,进而无法基于此ID发起正确的网络请求。具体表现如下:

  1. 项目A的数据格式:{ name: 'xiaoming', nick_name: '小明', userID: '9527' }
  2. 项目B的数据格式:{ userInfo: { name: 'xiaoming', nick_name: '小明', userID: '9527' } }

由于插件默认将整个state对象存储起来,导致数据多了一层userInfo外壳,从而引发格式不一致的问题。

为了去掉userInfo这一层外壳,我们需要自定义序列化和反序列化逻辑。修改后的Store配置如下:

ts 复制代码
import { defineStore } from 'pinia';

export const useUserInfoStore = defineStore('userInfo', {
    state: () => ({
        userInfo: null as any
    }),
    persist: {
        key: 'userInfo',
        storage: localStorage,
        paths: ['userInfo'], // 明确声明要持久化的字段
        serializer: {
            serialize: (state: any) => JSON.stringify(state.userInfo),
            deserialize: (str: string) => ({ userInfo: JSON.parse(str) })
        }
    } as any,
    actions: {
        setUserInfo(info: any) {
            this.userInfo = info;
        }
    }
});

经过上述配置,用户信息的存储结构变为{ name: 'xiaoming', nick_name: '小明', userID: '9527' },不再有额外的userInfo外壳,从而解决了跨项目登录时的格式不一致问题。

其他配置选项

在使用该插件时,虽然主要需求是"仅持久化对象中的特定字段",因此只使用了serializer配置项,但插件还支持其他功能。以下是部分可选配置:

ts 复制代码
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';

const pinia = createPinia();

pinia.use(piniaPluginPersistedstate, {
  storage: localStorage,
  key: 'myCustomStoreKey', // 自定义存储键名
  debug: true, // 启用调试
  serializer: {
    serialize(state) {
      // 自定义序列化逻辑
      return JSON.stringify(state);
    },
    deserialize(value) {
      // 自定义反序列化逻辑
      return JSON.parse(value);
    }
  },
  beforeHydrate(context) {
    // 在恢复状态之前执行的逻辑
    console.log('Before hydrating:', context.store.id);
  },
  afterHydrate(context) {
    // 在恢复状态之后执行的逻辑
    console.log('After hydrating:', context.store.id);
  },
  pick: ['userInfo.name', 'userInfo.email'], // 只持久化 userInfo 下的 name 和 email 属性
  // omit: ['userInfo.password'], // 省略 userInfo 下的 password 属性(与 pick 互斥)
});

// ... 定义你的 store ...

export default pinia;
相关推荐
用户693717500138413 小时前
我买的电视,我还不能研究它吗?
前端·后端·ai编程
Hilaku13 小时前
删了一个没用的 console.log,生产环境直接崩了!
前端·javascript·程序员
计算机魔术师13 小时前
Latent Space 解读 Anthropic 提交 S-1:拟以代码 AN 上市纳斯达克,H1 2026 营收 16.3B 美元
前端
2601_9498477514 小时前
Form-data 跨端三方库仓颉适配全流程
前端·javascript·flutter
zyseo814 小时前
谷歌SEO 内容更新焕新流程:让老页面重新起量
java·前端·javascript
夜雪一千14 小时前
标题特殊符号数据清洗实战:解决HTML实体、零宽字符、Emoji乱码踩坑
前端·html
richdata14 小时前
从采购承诺到库存周转:降低库存资金占用的六个计划杠杆
大数据·前端·javascript
计算机魔术师15 小时前
别人IPO发股票,Anthropic一口气搞出五类
前端
ai_coder_ai15 小时前
使用Web IDE边写自动化脚本
运维·前端·自动化
贾伟康16 小时前
【共创稿事节】一个 UserDataManager 管八类数据:Preferences 持久化的克制用法
java·服务器·前端·harmonyos·arkts·鸿蒙