欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue页面应用在F5刷新网页后vuex的state数据丢失?

程序员文章站 2022-06-02 22:03:14
...

vue单页面应用,用vuex来做全局的状态管理, 发现当刷新网页后,保存在vuex实例store里的数据会丢失


1.数据丢失产生原因??

因为store里的数据是保存在运行内存中的,当页面刷新(f5)时,页面会重新加载vue实例store里面的数据就会被重新赋值,从而产生了数据丢失。

2.问题解决思路??

  • state里的数据全部是通过请求来触发actionmutation来改变

  • 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/indeximport的几个模块,希望哪一部分的数据持久存储,将数据的名字在此配置就可以,目前我只想持久化存储user模块的数据

!