Pinia 会话级数据持久化Plugins-pinia

115 阅读1分钟

处理 页面刷新 store 数据重新载入,数据被重置问题(保持数据持久化)

定义piniaPlugin 并 挂在pinia实例上

// main.ts
import { createPinia } from 'pinia';
import { piniaPlugin } from './plugins/pinia-plugin' //自定义的pinia 插件文件
const app = createApp(App)
const cPinia = createPinia()
cPinia.use(piniaPlugin()) // 挂到createPinia() 上
app.use(cPinia) // 挂载pinia

随便定义2个 pinia hook

export const useLyonStore = defineStore('pinia-id1', {
  state: () => {
    return {
      lyon: 'xxxxx',
      count: 0
    }
  }
)
export const useLyonStore = defineStore('pinia-id2', {
  state: () => {
    return {
      lyon: 'yyyyy',
      count: 0
    }
  }
)

定义插件 piniaPlugin.ts 依赖于pinia提供的 PiniaPluginContext 和 $subscribe

import { toRaw } from "vue";
import { PiniaPluginContext } from 'pinia';
// setStorage
const setStorage = (key:string, value: any)=> {
  sessionStorage.setItem(key, JSON.stringify(value));
}
const getStorage = (key:string)=> {
  return sessionStorage.getItem(key) ? JSON.parse(sessionStorage.getItem(key) as string) : {}
};
type Options = {
  key?: string,
  piniaId?: string[]
}
const __defaultOptions:string ='Lyon'
// 定一个pinia 持久化插件
export const piniaPlugin = (options: Options ) => {
// 柯里化???
  return (context: PiniaPluginContext) => {
    console.log(context);
    const { store } = context
    const data = getStorage(`${ options?.key ?? __defaultOptions }_${store.$id}`)
    // $subscribe 监听store 触发
    store.$subscribe(() => {
      setStorage(`${ options?.key ?? __defaultOptions }_${store.$id}`, toRaw(store.$state))
    })
    console.log(store)
    return {
      ...data
    }
  }
}

Tip: 感谢博主:小满zs助我成长