分享一个Pinia存储的数据持久化插件
2023-12-13 04:08:32
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: 10000,
}
const Login = (): Promise<User> => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
name: '独孤求败',
age: 10000,
})
}, 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
文章来源:https://blog.csdn.net/lwf3115841/article/details/134960689
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!