手写Pinia存储的数据持久化插件
Pinia和Vuex的通病
Pinia和vuex的通病就是,页面刷新会导致数据丢失
解决通病
一、新建store
import { defineStore } from 'pinia'
//单独存放Store的名字  $id
import { Names } from './store-name'
type User = {
  name: string
  age: number
}
let res: User = {
  name: '孙悟空',
  age: 999,
}
const Login = (): Promise<User> => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        name: '孙悟空',
        age: 999,
      })
    }, 2000)
  })
}
export const useTestStore = defineStore(Names.TEST, {
  state: () => {
    return {
      user: <User>{},
      name: '飞机',
    }
  },
  //类似computed 修饰一些值
  getters: {
    newName():string {
      return `new--${this.name}-${this.getUserAge}`
    },
    getUserAge():number {
      return this.user.age
    }
  },
  // 类似methods 可以同步  异步  提交state
  actions: {
    setName() {
      this.name = '孙悟空'
    },
    async setUser() {
      this.user = await Login()
      this.setName()
    },
  },
})
//base
export const  useBaseStore = defineStore(Names.BASE, {
  state: () => {
    return {
      baseCurrent:1
    }
  }
})
存放store名字的文件
store-names.ts
//存放store的名字
export const  enum Names {
  TEST = 'TEST',
  BASE = 'BASE'
}
二、在main.ts中引入并使用手写的插件
main.ts
import { createApp, toRaw } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import './assets/main.css'
import piniaToLocalStoragePlugin from './stores/piniaToLocalStoragePlugin'
const app = createApp(App)
const store = createPinia()
store.use(
  piniaToLocalStoragePlugin({
    key: 'pinia', // 这是给缓存到本地时,加一个特殊的前缀,以免造成污染到其他缓存数据
    needKeepIds: ['BASE','TEST'], // 对于特定store进行持久化,store的名字都在store-names文件中抽离出来了,空或者不传,则对所有的store进行缓存到本地
  })
)
app.use(router)
app.use(store)
app.mount('#app')
三、手写的持久化插件
这个就是本文的主角了
piniaToLocalStoragePlugin.ts
import type { PiniaPluginContext } from 'pinia'
import { toRaw } from 'vue'
type Options = {
  key: string
  needKeepIds?: string[]
}
// 来个持久化存储的函数
const setStorage = (key: string, value: any) => {
  localStorage.setItem(key, JSON.stringify(value))
}
// 来个取的函数
const getStorage = (key: string) => {
  return localStorage.getItem(key)
    ? JSON.parse(localStorage.getItem(key) as string)
    : {}
}
const __piniaKey__: string = 'piniaKey'
const piniaToLocalStoragePlugin = (options: Options) => {
  const { key, needKeepIds = [] } = options
  //使用函数柯里化
  return (context: PiniaPluginContext) => {
    const { store } = context
    if (needKeepIds.length === 0) {
      //没有指定存全部
      // 有个监听是$subscribe  1. 先监听是否改变了store的内容 改变了就存
      store.$subscribe(() => {
        console.log(' change' )
        //无论哪个 state  所有的改变都走这个函数  所以我们可以在这里搞一些动作
        setStorage(`${key ?? __piniaKey__}-${store.$id}`, toRaw(store.$state))
      })
    } else {
      //有指定要存哪些
      //使用短路运算
      needKeepIds.includes(store.$id) &&
        store.$subscribe(() => {
          setStorage(`${key ?? __piniaKey__}-${store.$id}`, toRaw(store.$state))
        })
    }
    //2. 获取本地存储的localStorage 有就放在页面上
    const data = getStorage(`${key ?? __piniaKey__}-${store.$id}`)
    // console.log('data', data) //取到data了 怎么送给store呢
    return {
      ...data,
    }
  }
}
export default piniaToLocalStoragePlugin
手写Pinia存储的数据持久化插件的更多相关文章
- vuex数据持久化插件--指定持久化特定的值
		指定需要持久化的state,配置如下 import createPersistedState from "vuex-persistedstate" conststore = new ... 
- 手写vue双向绑定数据
		来一张原理图: 实现思路: (1)绑定data 种的数据,为每个数据添加指令.通过Object,defineProperty() 来通知属性是否更改 (2) 找到每个DOM节点的指令.绑定事件.并绑定 ... 
- 自己手写简约实用的Jquery tabs插件(基于bootstrap环境)
		一直想改版网站首页的图书展示部分,以前的展示是使用BootStrap的传统的collapse,网页篇幅占用大,也不够美观,操作也相对来说比较麻烦.于是有了自己利用Jquery来做一个图书展示的tabs ... 
- 一阶段项目 总结 之 两张图片对比 手写 jquery  也可以使用beer slider 插件
		<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title> ... 
- vuex-persist数据持久化存储插件
		Vuex 解决了多视图之间的数据共享问题.但是运用过程中又带来了一个新的问题是,Vuex 的状态存储并不能持久化.也就是说当你存储在 Vuex 中的 store 里的数据,只要一刷新页面,数据就丢失了 ... 
- vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件
		vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ... 
- iOS数据持久化存储:归档
		在平时的iOS开发中,我们经常用到的数据持久化存储方式大概主要有:NSUserDefaults(plist),文件,数据库,归档..前三种比较经常用到,第四种归档我个人感觉用的还是比较少的,恰恰因为用 ... 
- IOS开发--数据持久化篇之文件存储(一)
		前言:个人觉得开发人员最大的悲哀莫过于懂得使用却不明白其中的原理.在代码之前我觉得还是有必要简单阐述下相关的一些知识点. 因为文章或深或浅总有适合的人群.若有朋友发现了其中不正确的观点还望多多指出,不 ... 
- 转载 -- iOS数据持久化存储
		作者:@翁呀伟呀 授权本站转载 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方 ... 
- vuex数据持久化存储
		想想好还是说下vuex数据的持久化存储吧.依稀还记得在做第一个vue项目时,由于刚刚使用vue,对vue的一些基本概念只是有一个简单的了解.当涉及到非父子组件之间通信时,选择了vuex.只是后来竟然发 ... 
随机推荐
- 手把手教你玩转 Gitea|在 Windows 系统上安装 Gitea
			Gitea 支持在 Windows 系统上安装和使用.Gitea 本身作为一个单体应用程序,即点即用,如需长期驻留作为后台服务并开机运行就要依靠 Windows 服务工具 sc.exe. 通过本文,你 ... 
- NodeJS 服务 Docker 镜像极致优化指北
			这段时间在开发一个腾讯文档全品类通用的 HTML 动态服务,为了方便各品类接入的生成与部署,也顺应上云的趋势,考虑使用 Docker 的方式来固定服务内容,统一进行制品版本的管理.本篇文章就将我在服务 ... 
- RAID5 IO处理之重构代码详解
			1 作用 当阵列降级时,可以添加一块新盘进行重构,以恢复阵列的冗余. 2 发起重构 可以通过以下命令md并发起重构: mdadm -C /dev/md0 --force --run -l 5 -n 3 ... 
- 华为设备配置和使用FTP服务命令
			配置SFTP Server与Client server:aaa 进入aaa视图 local-user huawei2 password cipher huawei2 设置用户名和密码 local-us ... 
- Volatile介绍
			介绍 volatile 是 Java 虚拟机提供的轻量级的同步机制,它可以保证可见性(缓存一致性协议)和有序性(禁止指令重排序,也就是通过内存屏障来实现),但是不保证原子性. JMM 介绍 JMM 是 ... 
- Linux基础_3_文件/文件夹权限管理
			注:权限遮罩码: 控制用户创建文件和文件夹的默认安全设置,文件默认权限为666-umask的值,文件夹默认权限为777-umask的值. root默认0022,普通用户默认0002. 文件的默认权限不 ... 
- Vue学习之--------深入理解Vuex、原理详解、实战应用(2022/9/1)
			@ 目录 1.概念 2.何时使用? 3.搭建vuex环境 3.1 创建文件:src/store/index.js 3.2 在main.js中创建vm时传入store配置项 4.基本使用 4.1.初始化 ... 
- JavaScript基础&实战(2)js中的强制类型转换、运算符、关系运算符、逻辑运算符、条件运算符
			文章目录 1.强制类型转换Number 1.1 代码 1.2 测试结果 2.进制表示 2.1 代码 2.2 测试结果 3.强制类型转换为Boolea 3.1 代码 3.2 测试结果 4.运算符 4.1 ... 
- Vitepress搭建组件库文档(下)—— 组件 Demo
			上文 <Vitepress搭建组件库文档(上)-- 基本配置>已经讨论了 vitepress 搭建组件库文档的基本配置,包括站点 Logo.名称.首页 home 布局.顶部导航.左侧导航等 ... 
- 一、什么是Kubernetes
			一.什么是Kubernetes 它是一个全新的基于容器技术的分布式架构领先方案,确切地说,Kubernetes是谷歌严格保密十几年的秘密武器Borg的一个开源版本.Borg是谷歌内部使用的大规模集群 ... 
