pinia优雅的持久化数据

344 阅读2分钟

vue3里数据缓存还在用插件 就out了

应用方式

export const useUserStore = defineStore("user", () => {
    //缓存token到localstorage
    let token = storageRef<string>('', { key: "user-store", field: "token" });
})

  • 不在使用第三方插件
  • 通过vue3新特性customRef

前言:本来是想通过watch或者computed来实现缓存功能,但是要多写太多的代码,结合下两个概念就联想到了vue3中的新特性customRef功能

1.封装一个缓存的函数

新建一个storage.ts文件

type StorageTarget = 'localStorage' | 'sessionStorage' | 'all'
type LocalConfig = {
    key: any,
    field: string,
}

/**
 * 自定义缓存的ref
 * @param value {默认值}
 * @param option  {对应storage的配置}
 * @param target  {缓存目标}
 * @returns 
 */
export let storageRef = <T>(value: T, option: LocalConfig, target: StorageTarget = 'localStorage') => {
    return customRef((track, trigger) => {
        return {
            get() {
                track()
                let storage_value: T = (target == 'localStorage' ? getLocal : target == 'sessionStorage' ? getSession : getStorage)(option.key, option.field) || value
                return storage_value
            },
            set(val) {
                trigger();
                (target == 'localStorage' ? setLocal : target == 'sessionStorage' ? setSession : setStorage)(option.key, option.field, val)
                value = val
            }
        }
    })
}

2.定义缓存方法

/**
 * 
 * @param key storage里的key
 * @param field  storage里的字段名
 * @param value   storege里的字段值
 */
export let setLocal = (key: string, field: string, value: any) => {
    let currentLocal: Record<string, any> = JSON.parse(localStorage.getItem(key) as any) || {};
    currentLocal[field] = value;
    localStorage.setItem(key, JSON.stringify(currentLocal))
}
/**
 * 
 * @param key  storage里的key
 * @param field storage里的字段名
 * @returns 
 */
export let getLocal = (key: string, field?: string): any => {
    if (!field) {
        return JSON.parse(localStorage.getItem(key) as any) || null;
    }
    return JSON.parse(localStorage.getItem(key) as any)?.[field] || null;
}

3.声明pinia里的store变量

   //基础类型
   let token = storageRef<string>('', { key: "user-store", field: "token" });
   //引用类型
    let userInfo = storageRef<CurrentCom>({
        id: "",
        name: "",
    }, { key: "user-store", field: "userInfo" });

4.更新数据并触发缓存

//基础类型
token.value='xxxxxx'
//基础类型
userInfo.value={...userInfo.value,name:"张三"}

5.修改缓存到Session或同时缓存local和sesstion中

let token = storageRef<string>('', { key: "user-store", field: "token" },"all");

6.更多缓存方式

export let setSession = (key: string, field: string, value: any) => {
    let currentLocal: Record<string, any> = JSON.parse(sessionStorage.getItem(key) as any) || {};
    currentLocal[field] = value;
    sessionStorage.setItem(key, JSON.stringify(currentLocal))
}
export let getSession = (key: string, field?: string): any => {
    if (!field) {
        return JSON.parse(sessionStorage.getItem(key) as any) || null;
    }
    return JSON.parse(sessionStorage.getItem(key) as any)?.[field] || null;
}
export let getStorage = (key: string, field: string) => {
    let sessionData = getSession(key, field);
    let localData = getLocal(key, field);
    //不合并
    return sessionData || localData
}
export let setStorage = (key: string, field: string, value: any) => {
    setLocal(key, field, value);
    setSession(key, field, value)
}