Pinia持久化
pinia-plugin-persist插件实现Pinia的数据持久化
食用方法
安装
# npm npm install pinia-plugin-persist
# yarn yarn add pinia-plugin-persist
# pnpm pnpm add pinia-plugin-persist
|
store/index.ts配置
import { createPinia } from 'pinia' import piniaPersist from 'pinia-plugin-persist'
const pinia = createPinia() pinia.use(piniaPersist)
|
tsconfig.ts添加配置
{ "compilerOptions": { "types": [ "pinia-plugin-persist" ] }, }
|
Usage
源码即文档
export interface PersistStrategy { key?: string; storage?: Storage; paths?: string[]; } export interface PersistOptions { enabled: true; strategies?: PersistStrategy[]; } declare type Store = PiniaPluginContext['store']; declare module 'pinia' { interface DefineStoreOptionsBase<S, Store> { persist?: PersistOptions; } }
|
1. 基本使用
import { defineStore } from "pinia"
export const useStore = defineStore("StoreId", { state: () => ({ foo: "foo", bar: "bar" }), persist: { enabled: true, strategies: [ { key: 'user', storage: localStorage, path: ['foo'], }, ] } })
|
开启 enabled 之后,默认会对整个 Store 的 state 内容进行 sessionStorage 储存。
2. 进阶用法
strategies 字段说明:
| 属性 |
描述 |
| key |
自定义存储的 key,默认是 store.$id |
| storage |
可以指定任何 extends Storage 的实例,默认是 sessionStorage |
| paths |
state 中的字段名,按组打包储存(默认所有 state 都会进行缓存,通过 paths 指定要持久化的字段,其余的则不会进行持久化) |
import { defineStore } from "pinia"
export const useStore = defineStore("YourStore", () => { const foo = ref("foo") const bar = ref("bar") return { foo, bar } }, { enabled: true, strategies: [{ key: "custom storageKey", storage: localStorage, paths: ["foo", "bar"] }] })
|
storage 属性可以使用任何继承自 Storage 协议的对象,自定义存储对象也可以,如下 cookiesStorage 为例
import Cookies from 'js-cookie'
const cookiesStorage: Storage = { setItem (key, state) { return Cookies.set('accessToken', state.accessToken, { expires: 3 }) }, getItem (key) { return JSON.stringify({ accessToken: Cookies.getJSON('accessToken'), }) }, }
export const useStore = defineStore("YourStore", () => { const foo = ref("foo") const bar = ref("bar") const accessToken = ref("xxx") return { foo, bar, accessToken } }, { enabled: true, strategies: [{ key: "token", storage: cookiesStorage, paths: ["accessToken"] }] })
|
源码解读
type Store = PiniaPluginContext['store']; type PartialState = Partial<Store['$state']>;
export const updateStorage = (strategy: PersistStrategy, store: Store) => {
const storage = strategy.storage || sessionStorage const storeKey = strategy.key || store.$id
if (strategy.paths) { const partialState = strategy.paths.reduce((finalObj, key) => { finalObj[key] = store.$state[key] return finalObj }, {} as PartialState) storage.setItem(storeKey, JSON.stringify(partialState)) } else { storage.setItem(storeKey, JSON.stringify(store.$state)) } }
export default ({ options, store }: PiniaPluginContext): void => {
if (options.persist?.enabled) { const defaultStrat: PersistStrategy[] = [{ key: store.$id, storage: sessionStorage, }]
const strategies = options.persist?.strategies?.length ? options.persist?.strategies : defaultStrat
strategies.forEach((strategy) => { const storage = strategy.storage || sessionStorage const storeKey = strategy.key || store.$id const storageResult = storage.getItem(storeKey)
if (storageResult) { store.$patch(JSON.parse(storageResult)) updateStorage(strategy, store) } })
store.$subscribe(() => { strategies.forEach((strategy) => { updateStorage(strategy, store) }) }) } }
|