场景重现
相信很多小伙伴在使用Vuex
存储状态数据时,都遇到过这样的尴尬处境:
浏览器在未刷新、回退、前进时,
Vuex
一切正常;当进行刷新、回退、前进(之后简称:骚操作)时,发现
Vuex
存储的状态值,都变成了初始值!
oh~no~ 😫 这不是我要的效果!!
好不容易从API
拿过来的基础数据,都没了~一朝回到解放前!
产生原因
在解决问题前,我们先来捋一捋~为啥会这样呢?
Vuex
是js工程,数据是存储在内存中,在进行骚操作时,会让Vuex
重新加载,致使数据全部还原成初始值!
解决思路
Vuex
既然在进行这些骚操作时会丢失,那是不是可以考虑用localStorage
、sessionStorage
甚至Cookie
来持久化存储Vuex
呢?
答案当然是可以的!
我们去翻翻 Vuex官网,可以看到Vuex
提供了非常方便的插件功能来帮助我们来搞定这个需求~
废话不多说,直接上代码~
// @/store/plugins/createPersistedPlugin.js
export default function createPersistedPlugin(options = { key: 'store' }) {
return store => {
// 1. 判断`sessionStorage`中是否有`Vuex`快照
let sessionStore = JSON.parse(sessionStorage.getItem(options.key))
// 若无,则使用初始值, 否则使用快照的值
sessionStore && store.replaceState(sessionStore)
// 临时工,用完就解雇了~
sessionStore = null
// 2. 监听`Vuex`中`mutation`的变化
store.subscribe((mutation, state) => {
// 3. 动态存储`Vuex`快照至`sessionStorage`中
sessionStorage.setItem(options.key, JSON.stringify(state))
})
}
}
使用方法:
// @/store/index.js
import createPersistedPlugin from './plugins/createPersistedPlugin.js'
const persistedPlugin = createPersistedPlugin()
const store = new Vuex.Store({
state,
// 其他代码
mutations,
plugins: [persistedPlugin]
})
至此,再也不用担心测试员进行骚操作啦~😄
总结
以上代码也就抛砖引玉~还有更多可以完善的余地,如:
- 将
sessionStorage
提炼到options
中,可以根据不同业务场景使用对应的持久化对象,如localStorage
- 在
options
中加上一个expires
有效期,在expires
内有效,让功能更加细致化 - 添加
include
、exclude
字段,让state
可以选择性的更替快照 - and so on...
- 如有你有更好的
idea
,欢迎留言~
这是我的第一篇博文,写的不好的地方还请大家多多指教!轻点吐槽~
谢谢!☕️~