引言
vue3现在比较常用的状态管理是pinia,和vuex一样,我们在某些场合下也需要对状态持久化。本文将讨论这个话题。
持久化的实现
要实现pinia的持久化,我们肯定要像vuex一样引入一个插件,这个插件就是pinia-plugin-persistedstate
,官方文档在此。
你可以直接通过以下其中一个命令安装
csharp
npm i pinia-plugin-persistedstate -S
yarn add pinia-plugin-persistedstate
pnpm add pinia-plugin-persistedstate -S
并将该插件添加到你的pinia
javascript
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
插件的基本使用
参考官方文档,你可以直接在需要持久化的store中的state配置后设置persist:true
。
此外,persist还可以是一个对象,它接收如下的参数:
具体用法实例参考文档或注释说明。
特别需要说明的,如果只需要局部字段的持久化,我们可以使用配置中的paths属性来实现。例如
css
state:()=>({
username:'admin',
nickname:"管理员",
token:"",
role:"admin"
})
我们只需要对username和nickname持久化,其它字段不需要,我们可以通过
css
persist:{
paths:['username','nickname']
}
paths中还支持字段路径配置,如文档所示的save.me
css
import { defineStore } from 'pinia'
export const useStore = defineStore('store', {
state: () => ({
save: {
me: 'saved',
notMe: 'not-saved',
},
saveMeToo: 'saved',
}),
persist: {
paths: ['save.me', 'saveMeToo'],
},
})
持久化数据加密处理
数据持久化之后我们还得考虑数据是否要加密,就像上文的role
字段很明显是用于用户角色控制的,不加密处理就可以通过F12
修改,功能就白做了。为此,引入了secure-ls。
其可以指定对我们存入LocalStorage
的字段选择合适的加密算法(通过配置中的encodingType
指定)将存入LocalStorage
的数据加密。
配合pinia-plugin-persistedstate
使用的话,我们可以先定义一个"类Storage"。
typescript
import type { StorageLike } from 'pinia-plugin-persistedstate'
import SecureLS from 'secure-ls'
const ls = new SecureLS({
isCompression: false, //不压缩
//自定义秘钥
encryptionSecret: 'ddddgxxx'
})
export const SelfStorage: StorageLike = {
setItem(key: string, value: string) {
ls.set(key, value)
},
getItem(key: string): string | null {
return ls.get(key)
}
}
之所以可以这样,其实也是pinia-plugin-persistedstate
的配置项中的storage?: StorageLike;
,storage
的类型是StorageLike
,其类型定义如下:
ini
type StorageLike = Pick<Storage, 'getItem' | 'setItem'>;
由此,可以大概知道,pinia-plugin-persistedstate
最终调用的是给定Storage
的setItem
和getItem
方法,只要我们自定义的Storage
实现了这两个方法,我们甚至可以把全局状态存储在cookie
设置是webSql
中!对于我们需要加密这个需求,secure-ls
更方便一些,因此文中选择了它。
总结
我们要想对pinia的全局状态持久化,可以选择使用插件pinia-plugin-persistedstate
;而要想对这些状态数据进一步加密处理,我们可以通过自定义Storage
(类似于后端中的接口实现)来结合一些加密库,例如secure-ls
来实现。