解决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
还没有评论,来说两句吧...