解决redux/Vuex刷新页面数据丢失问题

前言

先简单描述一下需求:

  • A页面和B页面都需要通过同一个接口获取的数据来展示页面;
  • B是A的子页面,从A页面可以跳转到B页面;

思考

从减少页面的http请求数来达到性能优化的方面来考虑:可不可以A跳到B页面后,不再ajax请求数据,而是直接获取A页面Model里的数据?(如图)

在这里插入图片描述

尝试

按上述思路可以达到需求。但同时也发现一个问题:在重新刷新B页面时,B页面上显示的数据为空。

分析

Redux一个用于应用程序状态管理的开源JavaScript库,本质是管理组件数据状态的。刷新浏览器,相当于重新开启应用,必定会从最初的状态重新开始。如果想获取值,要么向后台发送请求,要么将值本地存储,从本地存储去取值。单说刷新浏览器,肯定是回复到最初状态,相当于什么也没做。

这里也涉及到前端路由和后端路由的问题。前端路由分为hash模式和history模式,我们从A页面跳转到B页面,本质上并没有从后端重新请求数据,而是前端通过正则匹配路由规则从而显示相应的页面(例:网易云音乐网页版)。

页面间数据交互的方式有很多种,在实际项目中我们要从多方面考虑去选择最优的方法。例如要考虑A页面是否是B页面的唯一来源、是否还能通过其它页面跳转至B页面…
实践是理论基础到真实能力的一种转化。在实际的业务场景中要前言使用基础,去验证基础,去通过基础来设计更合理的方案。

扩展(解决方案)

Vuex

思路:在页面刷新前将Vuex里的数据保存到 sessionStorage 中,进入应用时再从 sessionStorage 中取出数据并替换 store 的state,还原之前的状态;在Redux中也同理。

/**
 * 缓存Vuex里的数据,解决页面刷新Vuex数据丢失问题
 * @param {*} type 缓存方式 sessionStorage 和 localStorage ,默认是sessionStorage
 */
export function cacheVuex(store, type = sessionStorage) {
  if (type.getItem('_store')) {
    store.replaceState(
      Object.assign({}, store.state, JSON.parse(type.getItem('_store')))
    );
  }
  window.addEventListener('beforeunload', () => {
    type.setItem('_store', JSON.stringify(store.state));
  });
}

1.redux状态的持久化,保证页面刷新或者关闭后能恢复状态

代码如下
let initialState={};
if(localStorage.getItem('store')){
  initialState=JSON.parse(localStorage.getItem('store'));
}

// 1. Initialize
const app = dva({
  history: browserHistory,
  initialState:initialState
});

window.onunload=function () {
  localStorage.setItem('store',JSON.stringify(app._store.getState()));
};
原理

使用sessionStorage或者localStorage来达到数据存储;

缺点

因为dva中inititalState优先级比model中state高,整个状态持久化后,model State的结构改变,例如添加新key,会因为缓存导致无法应用,此方案有缺点。

2.解决redux刷新页面数据丢失问题(使用redux-persist持久化数据存储)

参考链接:https://segmentfault.com/a/1190000018150177


版权声明:本文为weixin_42755677原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。