需求

Pinia和VueX一样存在页面刷新状态丢失的问题。

为了防止数据丢失,可以写一个Pinia插件缓存值。

分析

前端可以使用LocalStorage、SessionStorage或Cookie持久化数据。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { toRaw } from 'vue'
import { PiniaPluginContext } from "pinia"

type Options = {
key?: string
}

const __piniaKey__ = "yajue"

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): {}
}

// Pinia内部会调用这个插件函数,并传一些参数
// 函数柯里化,同时接收用户配置和Pinia传递配置
const piniaPlugin = (options:Options)=> {
return((context: PiniaPluginContext)=> {
const { store } = context

// 取缓存值
const data = getStorage(`${options?.key ?? __piniaKey__}-${store.$id}`)

// 值改变时设置新值
store.$subscribe(()=> {
// 存的时候不要放代理对象,记得变成原始对象
setStorage(`${options?.key ?? __piniaKey__}-${store.$id}`,toRaw(store.$state))
})

// 返回值会交给仓库的state
return {
...data
}
})
}