手写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.只是后来竟然发 ...
随机推荐
- 超强的纯 CSS 鼠标点击拖拽效果
背景 鼠标拖拽元素移动,算是一个稍微有点点复杂的交互. 而在本文,我们就将打破常规,向大家介绍一种超强的仅仅使用纯 CSS 就能够实现的鼠标点击拖拽效果. 在之前的这篇文章中 -- 不可思议的纯 CS ...
- Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
参考书籍<mysql是怎样运行的> 非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容 书中还讲解了本文没有提到的子查询优化内容, 本文只总结了常见的子查询是如何优化的 系列文章目录 ...
- java连接数据库加载驱动到java项目
java连接数据库 package com.cook.zheng; import java.sql.Connection; import java.sql.DriverManager; public ...
- C语言经典编程100题
程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月 后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析: 兔子的规律为数列1,1 ...
- P 算法与 K 算法
P 算法与 K 算法 作者:Grey 原文地址: 博客园:P 算法与 K 算法 CSDN:P 算法与 K 算法 说明 P 算法和 K 算法主要用来解决最小生成树问题,即:不破坏连通性删掉某些边,使得整 ...
- 实现etcd服务注册与发现
转载自:实现etcd服务注册与发现 0.1.目录结构 . ├── api │ └── main.go ├── common │ └── common.go ├── docker-compose ...
- 13.内建函数eval()
eval函数 eval()函数十分强大 -- 将字符串当成有效的表达式来求值并返回计算结果 例如下图,eval会将字符串的引号去掉并且计算返回结果
- settings.py 配置汇总
数据库配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': ' ', #数据库名称 ...
- k8s集群正常kubectl用不了
今天有个客户反馈k8s集群服务正常,业务也正常.kubectl get no敲入这个命令就有夯住了 仔细去检查配置发现少了一个config 最后在master-2上的config文件cp拷一份过来问题 ...
- kubeEdge的MetaManager模块简介
MetaManager 是edged和edgehub之间的消息处理器,它还负责将元数据存储到轻量级数据库SQLite或从中检索元数据(metadata). 根据以下不同的operation接收不同类型 ...