策略和方法
- 使用
localStorage
:
- 在Pinia的
store
中,通过watch
监听关键状态数据的变化。例如,假设我们有一个userInfo
状态:
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: null
}),
actions: {
setUserInfo(info) {
this.userInfo = info
}
}
})
const userStore = useUserStore()
watch(() => userStore.userInfo, (newValue) => {
localStorage.setItem('userInfo', JSON.stringify(newValue))
})
- 在`store`初始化时,从`localStorage`中读取数据并设置到状态中:
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: JSON.parse(localStorage.getItem('userInfo')) || null
}),
actions: {
setUserInfo(info) {
this.userInfo = info
}
}
})
- 使用
sessionStorage
:与localStorage
类似,区别在于sessionStorage
的数据在页面会话结束(关闭页面)时会被清除。用法基本一致,只需将localStorage
替换为sessionStorage
。
- 利用插件:可以编写一个Pinia插件来统一处理状态的持久化。
import { createPiniaPlugin } from 'pinia'
const persistPlugin = createPiniaPlugin((context) => {
const { store } = context
const persistedState = localStorage.getItem(store.$id)
if (persistedState) {
store.$state = JSON.parse(persistedState)
}
store.$subscribe((mutation, state) => {
localStorage.setItem(store.$id, JSON.stringify(state))
})
})
const pinia = createPinia()
pinia.use(persistPlugin)
可能遇到的问题及解决方案
- 数据序列化和反序列化问题:
- 问题:
localStorage
和sessionStorage
只能存储字符串类型的数据。如果状态数据包含复杂对象(如函数、循环引用对象等),直接JSON.stringify
会出错。
- 解决方案:在存储前,对复杂对象进行处理,例如删除函数属性、处理循环引用。可以使用
structuredClone
(现代浏览器支持)来安全地复制对象,然后再进行JSON.stringify
。
- 存储容量限制问题:
- 问题:
localStorage
和sessionStorage
都有存储容量限制,一般在几MB左右。如果存储的数据量过大,会导致存储失败。
- 解决方案:对数据进行压缩处理,例如使用
lz-string
库对数据进行压缩后再存储。或者只存储关键数据,避免不必要的数据持久化。
- 跨域问题:
- 问题:在跨域场景下,不同域的页面可能无法共享
localStorage
或sessionStorage
数据。
- 解决方案:可以通过服务器端进行数据同步,例如使用后端接口来存储和读取数据,不同域的页面通过调用后端接口来实现数据的持久化和共享。