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. Vue实现长按图片识别图中二维码

    Vue实现长按图片识别图中二维码 思路:要想实现可以识别图片中的二维码,那必定是要将这张图进行上传操作,上传则需要file对象格式.不管是在H5还是APP中,展示的图片都是通过url的方式展示在img ...

  2. WiresShark

    WireShark 分析数据包技巧 确定WireShark的位置[是否在公网上] 选择捕获接口,一般都是internet网络接口 使用捕获过滤器 使用显示过滤器[捕获后的数据包还是很复杂,用显示过滤器 ...

  3. Kubeadm部署高可用K8S集群

    一 基础环境 1.1 资源 节点名称 ip地址 VIP 192.168.12.150 master01 192.168.12.48 master02 192.168.12.242 master03 1 ...

  4. 从0搭建vue3组件库:Shake抖动组件

    先看下效果 其实就是个抖动效果组件,实现起来也非常简单.之所以做这样一个组件是为了后面写Form表单的时候会用到它做一个规则校验,比如下面一个简单的登录页面,当点击登录会提示用户哪个信息没输入,当然这 ...

  5. 基于Seq2Seq和注意力机制的句子翻译

    Seq2Seq(Attention) 目录 Seq2Seq(Attention) 1.理论 1.1 机器翻译 1.1.1 模型输出结果处理 1.1.2 BLEU得分 1.2 注意力模型 1.2.1 A ...

  6. Tauri-Vue3桌面端聊天室|tauri+vite3仿微信|tauri聊天程序EXE

    基于tauri+vue3.js+vite3跨桌面端仿微信聊天实例TauriVue3Chat. tauri-chat 运用最新tauri+vue3+vite3+element-plus+v3layer等 ...

  7. $_SERVER["REQUEST_URI"],在 PHP 众多预定义服务器变量中,$_SERVER["REQUEST_URI"] 算是经常用到的,但是这个变量只有 apache 才支持

    例如访问:http://localhost/index.php?app=lunbo获取到的$_SERVER["REQUEST_URI"]为"/index.php?app= ...

  8. vulnhub靶场之CORROSION: 2

    准备: 攻击机:虚拟机kali.本机win10. 靶机:CORROSION: 2,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhub.com ...

  9. 用 VS Code 搞 Qt6:让信号和槽自动建立连接

    Qt 具备让某个对象的信号与符合要求的槽函数自动建立连接.弄起来也很简单,只要调用这个静态方法即可: QMetaObject::connectSlotsByName(...); connectSlot ...

  10. 如何开发Vite3插件构建Electron开发环境

    新用户购买<Electron + Vue 3 桌面应用开发>,加小册专属微信群,参与群抽奖,送<深入浅出Electron>.<Electron实战>作者签名版. 1 ...