前言
在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
发起正确的网络请求。具体表现如下:
- 项目
A
的数据格式:{ name: 'xiaoming', nick_name: '小明', userID: '9527' }
- 项目
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;