香~来自己动手做一款基于Pinia的可持久化插件吧~

2022-10-28 19:11:58 浏览数 (1)

01

前言

最近正在对AdminWork(naiveui)版本进行重构,这次重构可以说基本上是对框架的核心功能进行重写了一次。了解过AdminWork源码的小伙伴可能知道,在LayoutStore中有一个很大的全局响应式对象,当然这样做是没有问题的,可以随着项目的开发,这种模式可能显得不太好,不利于扩展和维护。

同时之前用 typescript 写的很多地方不太好,有很多冗余的代码和不合理的代码。这次也一并升级。

值得一说的是这次升级也给大家带来的了一款基于Pinia的可持久化插件。只需要简单的几个配置就可以让 state 进行本地化存储。

02

包含功能

先来看一下我们开发的这款插件有什么样的功能吧。

1、可以进行对 state 对象进行保存到 localStorage 或者 sessionStorage

2、可以把localStorage 或者 sessionStorage的数据恢复到 state对象中

3、可以进行禁用、启用

4、可以过滤某些不需要进行存储的字段

基本上功能也就这么多,虽然不太复杂,可是写好这些还是需要点耐心的。

下面我们先看一下数据类型:

代码语言:javascript复制
interface PresistType<S, Store> {
  enable: boolean
  option: Partial<{
    key: string
    storage: 'local' | 'session'
    include: (keyof S)[]
    exclude: (keyof S)[]
  }>
  resetToState?: ((store: Store) => void) | boolean
}

为了能更好的适配 typescript ,所以如果想要让 Pinia 认识我们自定义的选项,还需要进行声明,如下:

代码语言:javascript复制
declare module 'pinia' {
  export interface DefineStoreOptionsBase<S, Store> {
    presist?: Partial<PresistType<S, Store>>
  }
}

03

详细说明

从上面的类型定义中我们可以看所定义的字段并不多,下面我们一一介绍下各字段具体是什么含义。

  • enable

类型:boolean

默认:false

说明:该选项默认值是false,也就是说需要你显示的指定为 true,才会开启对某个Store的持久化功能。

  • option

类型:object

默认:undefined

说明:该选项包含着一系列其它选项,没有实际意义,具体看里面的选项

  • option.key

类型:string

默认值:某store中的id

说明:该选项可以指定缓存的键名,如localStore.set(key, xxxx),如果不指定默认值就是当然定义 store的 id名称

  • option.storage

类型:'local' | 'session'

默认值:'local'

说明:该选项只能指定 'local' | 'session' 其中的一种,可以指定是用哪种方式进行存储,如常用的 localStoreag 和 sessionStorage

  • option.include

类型:(keyof S)[]

默认:undefined

说明:该选项可以指定需要存储的哪些字段,不指定则是存储全部字段

  • option.exclude

类型:(keyof S)[]

默认:undefined

说明:该选项可以指定需要排队存储的哪些字段,不指定则是存储全部字段

  • resetToState

类型:((store:Store)=>void) |boolean

默认:undefined

说明:该选项可以指定是否需要从持久化中恢复数据到state中,如果是函数类型,则意味着自己指定恢复过程。

04

使用

1、安装使用:

由于我们并没有把插件托管到 npm 中,所以这里无需安装,直接把源码放到本地,然后进行使用

代码语言:javascript复制
import { createPinia } from 'pinia'
import PersistPlugin from './plugin/persist'

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

export default pinia

2、在某个Store中使用

代码语言:javascript复制
const useUserStore = defineStore('user-info', {
  state: () => {
    return {
      userId: 0,
      roleId: 0,
      token: '',
      userName: '',
      nickName: '',
      avatar: defaultAvatar,
    }
  },
  // 下面的选项是我们的具体配置
  presist: {
    enable: true,
    resetToState: true,
    option: {
      exclude: ['userName'],
    },
  },
})

使用起来还是比较简单的

最后说一下具体源码的获取方式,可以从github 或者 gitee 上下载AdminWork的 dev 分支,然后找到 src/store/plugin下面的文件。以后会放到npm上,方便下载使用

0 人点赞