avatar

麦兜的小站

MDO.INK

  • 首页
  • 随笔
  • 知识库
  • 归档
  • 动态
  • 标签
  • 关于
Home pinia优雅的持久化数据
文章

pinia优雅的持久化数据

Posted 2025-02-10 Updated 2025-02- 10
By power 已删除用户
8~11 min read

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

应用方式

export const useUserStore = defineStore("user", () => {

    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)
}
前端
License:  CC BY 4.0
Share

Further Reading

Jun 25, 2025

Vue实现顶部导航跟随页面联动效果

需求背景 最近也是应我一位同学的要求,给他的公司制作一个官网,那也就是拾起了一些基础的知识,搜索了一些其它的文章有实现这种效果的,但大多导航都是在侧边,然后点击导航对应的部分内容滑到最上面,跟我这次设...

Jun 20, 2025

Share.js - 一键分享到微博、QQ空间、QQ好友、微信、腾讯微博、豆瓣、Facebook、Twitter、Linkedin、Google+、点点

一键分享到微博、QQ空间、QQ好友、微信、腾讯微博、豆瓣、Facebook、Twitter、Linkedin、Google+、点点等社交网站,使用字体图标。 有两种安装方式: 使用npm npmi...

Jun 19, 2025

node express实现热更新

在使用node进行开发的时候,每次修改文件,都需要重启express服务很麻烦 我们可以使用nodemon这个库,修改文件后可以自动重启express服务。 安装: npminstall--save-...

OLDER

Axios二次封装,集成缓存

NEWER

pinia使用指南Pinia 是 Vue 新一代的状态管理器

Recently Updated

  • 如何实现接口幂等性
  • 10个npm工具包
  • How to set up PHP7.4 on MacOS.
  • Automa:一键自动化,网页数据采集与工作流程优化专家Automa:解锁自动化
  • Mac 下用 brew 搭建 LNMP

Trending Tags

thinkphp clippings

Contents

©2025 麦兜的小站. Some rights reserved.

Using the Halo theme Chirpy