vue页面应用在F5刷新网页后vuex的state数据丢失?
vue单页面应用,用vuex来做全局的状态管理, 发现当刷新网页后,保存在vuex实例store里的数据会丢失
1.数据丢失产生原因??
因为
store
里的数据是保存在运行内存中
的,当页面刷新(f5)
时,页面会重新加载vue实例
,store
里面的数据就会被重新赋值
,从而产生了数据丢失。
2.问题解决思路??
-
state
里的数据全部是通过请求
来触发action
或mutation
来改变 -
将
state
里的数据保存
一份到本地存储
(localStorage、sessionStorage、cookie)中
3.问题解决过程??
存储比较选择??
localStorage
是永久性存储,除非主动去删除。sessionStorage
是短暂性存储,关闭当前窗口/标签页就会删除;cookie
是根据你设置的有效时间来存储,但缺点是不能储存大数据而且不易读取,性能不佳。
因为单页面应用操作都是在
一个页面
跳转路由,而sessionStorage
可以保证打开页面时sessionStorage
的数据为空
;如果是localStorage
则会读取上一次打开页面的数据
相比之下
sessionStorage
更适合于单页面应用
那怎么用sessionStorage来保存state里的数据呢??
- 因为
state
里的数据是响应式
的,所以sessionStorage
存储也要跟随变化
。
由于vuex
规定所有state
里数据必须通过mutation
方法来修改
。
So第一种方案就是mutation
修改state
的同时修改sessionStorage
对应存储的属性。
第一种方案确实可以解决问题,但这种方法很明显让人觉得怪异,还不如直接用sessionStorage来做状态管理。
那怎么才能不用每次修改state
时同时也要修改sessionStorage
呢??
这时我们可以换一个思路,因为我们是只有在
刷新页面时
才会丢失state
里的数据,那有没有办法在点击页面刷新时
先将state
数据保存
到sessionStorage
,然后再刷新页面呢?? 当然有喽!
beforeunload
这个事件在页面刷新
时先触发
。那么这个事件应该在哪里触发呢?我们总不能每个页面都监听这个事件,所以我选择放在app.vue
这个入口组件中,这样就可以保证每次刷新页面都可以触发
。
- 在页面
加载时
读取sessionStorage
里的状态信息
,在页面刷新时
将vuex
里的信息保存
到sessionStorage
里
export default {
name: 'App',
created () {
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store") ) {
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload",()=>{
sessionStorage.setItem("store",JSON.stringify(this.$store.state))
})
}
}
- vuex持久化
vuex-persistedstate
安装
npm i -S vuex-persistedstate
在store
下的index.js
中引入及配置
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
})
因为
vuex-persistedstate
默认使用localStorage
来固化数据,而现在单页面应用中用到的是sessionStorage
,或是一些特殊情况要如何应对呢??(如:safari的无痕浏览模式)
sessionStorage存储方式
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
cookie存储方式
import persistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
export default new Vuex.Store({
// ...
plugins: [
persistedState({
storage: {
getItem: key => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, { expires: 7 }),
removeItem: key => Cookies.remove(key)
}
})
]
})
vuex-persistedstate默认持久化所有state,指定需要持久化的state
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的user
user: val.user
}
}
})]
此刻的
val
对应store/modules
文件夹下几个js文件存储的内容,也就是store/index
中import
的几个模块
,希望哪一部分的数据持久存储
,将数据的名字
在此配置
就可以,目前我只想持久化存储user
模块的数据
!
下一篇: DM8 DSC共享集群搭建部署