用Vue做项目开发很久了,对于vuex能用、会用,但是因为状态脱离页面和刷新丢失两个原因,一直都有种抵触,特别是一些简单的数据都是通过query或者本地存储就解决了,然而对于一些复杂内容,不可避免的还是要使用Vuex去处理(真香),但是刷新丢失的问题,的确叫人头大。最近闲下来,我们来研究下怎么干掉这个问题~


不大了解Vuex的同学,可以先去官网溜溜


由于Vuex的数据是存储在内存中的,相当于memory cache,当页面刷新的时候内存被清空重载新内容,原来的数据就丢了,为了解决这个我们可以借助浏览器的本地存储来解决,此时我们有两个选择

  • localStorage 真·持久存储
  • sessionStorage 会话期存储

相比之下localStorage太持久了,不主动清除都会一直在,而sessionStorage更符合Vuex会话期状态管理的设计初衷。因此下文中统一使用sessionStorage来做补充,解决问题。

有了补充对象之后,我们要做的只有两点

1、每次在mutation中set state的时候,同步的塞到sessionStorage一份

2、状态初始化的时候,从sessionStorage中读取相应内容并作为默认值(存在的话)

看起来很简单,于是第一版方案有了,

export default new Vuex.Store({
state: {
userLevel: sessionStorage.getItem('userLevel') || ''
},
mutations: {
SET_USERLEVEL(state, userLevel) {
sessionStorage.setItem('userLevel', userLevel)
state.userLevel = userLevel
}
},
modules: {
}
})

这个是解决问题了,但是每个mutation都要sessionStorage.setItem一下实在有点麻烦,而且初始化还要都getItem一遍,我很懒不想写。。。于是我们改进了第二版

const storeMaker = (state) => {
// 初始化
Object.keys(state).map((key) => {
// 判断类型获取本地存储数据
if (typeof state[key] === 'object') {
if (sessionStorage.getItem(key) && JSON.parse(sessionStorage.getItem(key))) {
state[key] = JSON.parse(sessionStorage.getItem(key))
}
} else if (typeof state[key] === 'number') {
if (sessionStorage.getItem(key) && parseInt(sessionStorage.getItem(key))) {
state[key] = parseInt(sessionStorage.getItem(key))
}
} else {
if (sessionStorage.getItem(key)) {
state[key] = sessionStorage.getItem(key)
}
}
}) // 重写set处理
return new Proxy(state, {
set: function(target, key, value) {
let temp = value
if (typeof temp === 'object') {
temp = JSON.stringify(temp)
} sessionStorage.setItem(key, temp)
return Reflect.set(target, key, value)
}
})
} export default new Vuex.Store({
state: storeMaker({
userLevel: ''
}),
mutations: {
SET_USERLEVEL(state, userLevel) {
state.userLevel = userLevel
}
},
modules: {
}
})

内容不多,主要定义了一个storeMaker的函数实现了两个功能

1、对传入的state初始值判断类型,并尝试从sessionStorage中读取数据替换默认值

2、通过Proxy重置state的set逻辑,添加同步保存到sessionStorage的逻辑

其实本来可以通过Proxy重置get逻辑处理取值的问题,但是由于vuex本身通过defineProperty函数重置了get逻辑,在这里使用proxy覆盖会有冲突,因此在初始化的时候直接读取sessionStorage。

同时也存在一些问题:

1、目前只处理了一级属性,二级以下属性没处理,对于初始化会有偏差。对于这点处理层级也不宜过深,因为过深的结构设计本来就并不合理,两层基本也足够了。基本处理就是对于state的每个key再去遍历一遍,如果是object(非null非数组非空对象)就重新proxy一下

2、可以尝试打包成npm包,或者写成Vuex的插件形式,方便使用

3、等等

~状态不好,先写到这,大家有兴趣一起来讨论,清清脑子再来补充~

联想到的一些点:

1、memory cache和disk cache?内存怎么清理?js垃圾回收机制?

2、SessionStorage怎么做到会话期缓存?

3、session机制怎么回事?

4、http的无状态?状态保持?客户端保持?服务端保持?

5、等等等等

发散开看看,一个地方真的能学到很多东西。。。

Vuex数据页面刷新丢失问题解决方案的更多相关文章

  1. 解决vuex数据页面刷新后初始化问题

    在vue项目的开发中经常会用到vuex来进行数据的存储,然而在开发过程中会出现刷新后页面的vuex的state数据初始化问题!下面是我用过的解决方法 利用storage缓存来实现vuex数据的刷新问题 ...

  2. 使用sessionStorage解决vuex在页面刷新后数据被清除的问题

    https://www.jb51.net/article/138218.htm 1.原因 2.解决方法 localStorage没有时间期限,除非将它移除,sessionStorage即会话,当浏览器 ...

  3. vue 使用localStorage解决vuex在页面刷新后数据被清除的问题

    通常,我们在使用vue编写页面时,会需要使用vuex在组件间传递(或者说共同响应)同一个数据的变化.例如:用户的登录信息. 下面,我们使用传递用户登录信息的例子来一步步解决这个问题. 首先,我们的第一 ...

  4. 【vue】使用localStorage解决vuex在页面刷新后数据被清除的问题

    通常,我们在使用vue编写页面时,会需要使用vuex在组件间传递(或者说共同响应)同一个数据的变化.例如:用户的登录信息. 下面,我们使用传递用户登录信息的例子来一步步解决这个问题. 首先,我们的第一 ...

  5. 解决vuex在页面刷新后数据丢失的问题

    一.原因 js代码是运行在内存中的,代码运行时的所有变量.函数也都是保存在内存中的. 刷新页面,以前申请的内存被释放,重新加载脚本代码,变量重新赋值,所以这些数据要想存储就必须存储在外部,例如:Loc ...

  6. 页面刷新vuex数据消失问题解决方案

    VBox持续进行中,哀家苦啊,有没有谁给个star. vuex是vue用于数据存储的,和redux充当同样的角色. 最近在VBox开发的时候遇到的问题,页面刷新或者关闭浏览器再次打开的时候数据归零.这 ...

  7. 页面刷新vuex数据消失问题解决方案 之 vuex中间件

    之前我写了一篇用ES6 Proxy方案解决数据同步的文章 页面刷新vuex数据消失问题解决方案. 今天和同事沟通这个vuex数据还原问题,我说我的方法很奇异.聊着聊着,同事咋不用  store.sub ...

  8. Vuex 页面刷新后store保存的数据会丢失 取cookie值

    在store.js中 export default new vuex.Store({ // 首先声明一个状态 state state:{ pcid: '', postList: [], } //更新状 ...

  9. vue路由传参页面刷新参数丢失问题解决方案

    最近项目中涉及到跨页面传参数和后台进行数据交互,看到需求之后第一反应就是用路由传参来解决:Vue中给我们提供了三种路由传参方式,下面我们一个一个的来看一下: 方法一:params传参: this.$r ...

随机推荐

  1. 超简单MVC应用程序播放WMV视频

    本篇博文,介绍给大家的是,在MVC应用程序中,播放Windows media video(.wmv) 视频文件. Insus.NET的实现方法,把media player组件,嵌入MVC的控制器的Co ...

  2. 解决MVC应用程序数据重复加载问题

    先来看看这个动画: 这是使用jQuery来实现数据加载,每点击一次,数据就加载一次.这源程序与实现来自<MVC应用程序JsonResult()的练习>http://www.cnblogs. ...

  3. SQL Server复制入门(二)----复制的几种模式

    简介 本系列文章的上一篇对复制是什么做了一个概述.本篇文章根据发布服务器,分发服务器和订阅服务器的组织方式和复制类型来讲述常用复制的几种模式. 模式的选择 选择复制的模式取决于多个方面.首先需要考虑具 ...

  4. Java基础——数组

    一.大数据 如果基本的整型和浮点型精度不能够满足需求,那么可以使用java.math包含中的两个类:BigInteger和BigDecimal. 这两个类处理包含任意长度数字序列的数值.BigInte ...

  5. JavaScript--事件对象(25)

    // JavaScript事件的一个重要的方面是它们拥有一些相对一致的特点,可以给开发提供强大的功能; // 最方便和强大的就是事件对象,它们可以帮你处理鼠标事件和键盘敲击方面的情况; // 此外还可 ...

  6. web自动化开发环境配置详解

    1.安装 nodejs Grunt和所有grunt插件都是基于nodejs来运行的, https://nodejs.org/ 安装完成之后在终端 node -v 查看安装版本 2.安装 grunt-C ...

  7. BZOJ3108 [cqoi2013]图的逆变换

    Description 定义一个图的变换:对于一个有向图\(G=(V, E)\),建立一个新的有向图: \(V'=\{v_e|e \in E\}\),\(E'=\{(v_b, v_e)|b=(u,v) ...

  8. Redis Linux版安装详解

    Redis介绍 我的Linux系统是CentOS7 1.安装Redis 官方下载地址:http://download.redis.io 使用Linux下载:wget http://download.r ...

  9. html垂直居中

    参考于http://www.cnblogs.com/yugege/p/5246652.html <!DOCTYPE html> <html lang="en"&g ...

  10. VMware Linux虚拟机与WIN7操作系统共享无线网络上网配置

    Linux虚拟机与WIN7操作系统共享无线网络上网配置 by:授客 QQ:1033553122 测试环境: CentOS-7-x86_64-DVD-1503-01.iso Vmware 9 实践操作: ...