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存储的数据持久化插件的更多相关文章

  1. vuex数据持久化插件--指定持久化特定的值

    指定需要持久化的state,配置如下 import createPersistedState from "vuex-persistedstate" conststore = new ...

  2. 手写vue双向绑定数据

    来一张原理图: 实现思路: (1)绑定data 种的数据,为每个数据添加指令.通过Object,defineProperty() 来通知属性是否更改 (2) 找到每个DOM节点的指令.绑定事件.并绑定 ...

  3. 自己手写简约实用的Jquery tabs插件(基于bootstrap环境)

    一直想改版网站首页的图书展示部分,以前的展示是使用BootStrap的传统的collapse,网页篇幅占用大,也不够美观,操作也相对来说比较麻烦.于是有了自己利用Jquery来做一个图书展示的tabs ...

  4. 一阶段项目 总结 之 两张图片对比 手写 jquery 也可以使用beer slider 插件

    <!DOCTYPE html><html> <head>  <meta charset="utf-8">  <title> ...

  5. vuex-persist数据持久化存储插件

    Vuex 解决了多视图之间的数据共享问题.但是运用过程中又带来了一个新的问题是,Vuex 的状态存储并不能持久化.也就是说当你存储在 Vuex 中的 store 里的数据,只要一刷新页面,数据就丢失了 ...

  6. vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

    vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...

  7. iOS数据持久化存储:归档

    在平时的iOS开发中,我们经常用到的数据持久化存储方式大概主要有:NSUserDefaults(plist),文件,数据库,归档..前三种比较经常用到,第四种归档我个人感觉用的还是比较少的,恰恰因为用 ...

  8. IOS开发--数据持久化篇之文件存储(一)

    前言:个人觉得开发人员最大的悲哀莫过于懂得使用却不明白其中的原理.在代码之前我觉得还是有必要简单阐述下相关的一些知识点. 因为文章或深或浅总有适合的人群.若有朋友发现了其中不正确的观点还望多多指出,不 ...

  9. 转载 -- iOS数据持久化存储

    作者:@翁呀伟呀 授权本站转载 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方 ...

  10. vuex数据持久化存储

    想想好还是说下vuex数据的持久化存储吧.依稀还记得在做第一个vue项目时,由于刚刚使用vue,对vue的一些基本概念只是有一个简单的了解.当涉及到非父子组件之间通信时,选择了vuex.只是后来竟然发 ...

随机推荐

  1. 220726 T2 Multisets (思维)

    题目描述 我们说一个可重集 AA 比可重集 BB 小,当且仅当对于两个可重集中出现次数不同的最小元素 xx ,元素 xx 在 AA 中出现次数更多. 例如,可重集 {1,2,3}1,2,3 就比可重集 ...

  2. SpringBoot(一) - SpringBoot 初识

    1.创建SpringBoot项目 1.1 使用Spring Initializr 的 Web页面创建项目 创建网址:https://start.spring.io/ 1.2 使用IDEA创建 省略: ...

  3. vivo互联网机器学习平台的建设与实践

    vivo 互联网产品团队 - Wang xiao 随着广告和内容等推荐场景的扩展,算法模型也在不断演进迭代中.业务的不断增长,模型的训练.产出迫切需要进行平台化管理.vivo互联网机器学习平台主要业务 ...

  4. 基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

    在前面随笔<基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理>中我们已经介绍过,对于相关的业务表的界面代码,我们已经尽可能把不同的业务逻辑 ...

  5. 研一小白入坑Go (time使用)

    1 package main 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 func main() { 9 // 获取当前时间 1 ...

  6. SpringBoot(七) - Redis 缓存

    1.五大基本数据类型和操作 1.1 字符串-string 命令 说明 set key value 如果key还没有,那就可以添加,如果key已经存在了,那会覆盖原有key的值 get key 如果ke ...

  7. 如何用Virtualbox搭建一个虚拟机

    序言 各位好啊,我是会编程的蜗牛,作为java开发者,我们肯定会接触Linux服务器,除了使用云服务搭建Linux服务器外,我们一般也可以在自己的电脑上安装虚拟机来搭建Linux服务器用于各种功能的验 ...

  8. springboot+thymeleaf中前台页面展示中、将不同的数字替换成不同的字符串。使用条件运算符

    主要用到的知识就是thyme leaf中的条件运算符 表达式:(condition)?:then:else 当条件condition成立时返回then.否则返回else 具体代码:<td th: ...

  9. JUC(3)

    文章目录 1.集合类不安全 2.在高并发情况下arraylist()并不安全 3.高并发下set并不安全 3.测试map(高并发情况下出现问题) 1.集合类不安全 2.在高并发情况下arraylist ...

  10. Kubernetes核心技术-Controller

    Kubernetes核心技术-Controller 内容 什么是Controller Pod和Controller的关系 Deployment控制器应用场景Deployment控制器应用 yaml文件 ...