解决刷新页面vuex store中数据丢失的问题
**问题背景:**页面刷新后,vuex中的数据丢失。这是因为:js代码是运行在内存中的,代码运行时的所有变量、函数也都是保存在内存中的。进行刷新页面的操作,以前申请的内存被释放,重新加载脚本代码,变量重新赋值,所以这些数据要想存储就必须存储在外部,例如:Local Storage、Session Storage、Index DB等。这些都是浏览器提供的API,让你可以将数据存储在硬盘上,做持久化存储。具体选择哪一个就根据你实际需求来选择。
解决思路:
在项目中,登录后,通过登录接口会获取到很多用户信息,首先将用户信息保存在vuex的store中,同时将这些信息也保存在sessionStorage中。这里需要注意的是vuex中的变量是响应式的,而sessionStorage不是,当你改变vuex中的状态,组件会检测到改变,而sessionStorage就不会了,页面要重新刷新才可以看到改变,所以应让vuex中的状态从sessionStorage中得到,这样组件就可以响应式的变化。
补充:
在客户端存储数据:HTML5提供了2种在客户端存储数据的新方法:localStorage没有时间期限,除非将它移除,sessionStorage即会话,当浏览器关闭时会话结束,有时间期限。
之前,这些都是由cookie完成的,但是cookie不适合大量数据的存储,因为它们由每个对服务器的请求来传递,这使得cookie速度很慢,而且效率不高。
代码如下:
1.在vuex中
const state = { token:sessionStorage.getItem(`token`)||``, userInfo:JSON.parse(sessionStorage.getItem(`userInfo`))||{}, roleInfoList:JSON.parse(sessionStorage.getItem(`roleInfoList`))||[], }; const getters = { }; const mutations = { //保存token setToken(state,token){ sessionStorage.setItem(`token`,token) state.token=token; }, //保存用户登录信息 setUserInfo(state, userInfo) { sessionStorage.setItem(`userInfo`, JSON.stringify(userInfo)) state.userInfo = userInfo; }, //保存菜单 setRoleInfoList(state,roleInfoList){ sessionStorage.setItem(`roleInfoList`, JSON.stringify(roleInfoList)) state.roleInfoList=roleInfoList }, } const actions = { updateToken(context,value){ context.commit('setToken',value) }, updateUserInfo(context,value){ context.commit('setUserInfo',value) }, updateRoleInfoList(context,value){ context.commit('setRoleInfoList',value) }, } export default { namespaced: true, state, getters, mutations, actions }
在vue组件中:
import {mapState, mapActions, mapMutations} from 'vuex' export default { methods: { //登录接口 getLoginInfo() { http.getLoginInfo({userToken}).then(data => { //将获取到的用户信息存在vuex中 this.setUserInfo({userInfo: data}); this.updateUserInfo(data); ...... this.$message('登录成功'); }).catch(e => { this.$message(e) }) }, ...mapActions(`user`,[`updateToken`,`updateUserInfo`,`updateRoleInfoList`]), ...mapMutations(`user`, [`setUserInfo`, `setToken`, `setRoleInfoList`]) } }
补充:storage只能存储字符串的数据,对于JS中常用的数组或对象不能直接存储。但我们可以通过JSON对象提供的parse和stringify将其他数据类型转化成字符串,再存储到storage中就可以了。
var obj = { name:'Jim' }; var str = JSON.stringify(obj); //存入 sessionStorage.obj = str; //读取 str = sessionStorage.obj; //重新转换为对象 obj = JSON.parse(str);