关键:页面登录标记与本地缓存标记不同,就刷新页面更新标记
起因
我在维护一个老项目,这项目把登录信息存到了本地存储,每个页面在data里获取了来用,这导致了用户开启新标签窗口重新登录,但之前打开的旧页面没刷新,我们知道data里获取的数据会被存储在自己的作用域,直到刷新页面才会重新执行data方法,那么这就导致了这个旧页面的执行的所有操作都是使用的旧信息,导致了一系列用户操作的出错。
第一种
那么我就想到在每个打开的页面上都加一个当前登录人标识,在接口做请求的时候在请求拦截器里对比标识与当前本地存储的真正登录人是否一样,标识不同就弹窗提醒用户刷新页面再执行操作。
第二种
app.vue
python
data() {
return {
loginUl: JSON.parse(localStorage.getItem("loginUl")),
};
},
mounted() {
document.addEventListener("visibilitychange", this.handleAddListener);
},
beforeDestroy() {
document.removeEventListener("visibilitychange", this.handleAddListener);
},
methods: {
handleAddListener(){
if(!JSON.parse(localStorage.getItem("loginUl"))||(JSON.parse(localStorage.getItem("loginUl"))&&this.loginUl.userId!=JSON.parse(localStorage.getItem("loginUl")).userId)){
window.location.reload(true);
}
},
}
在app.vue加一个页面是否失焦的判断,如果浏览器被最小化或当前标签页不再作为主窗口后就变回主窗口,那么就对比页面路由元信息meta的params的登录人ID与本地存储的登录人ID是否一致,不一致就直接强制刷新页面来获取最新信息,这样比在app.vue里做定时器循环对比要合理的多。
第三种
watch监听本地存储来决定是否刷新页面
可能出现的问题
一些用户在旧页面写满文字后没点击保存,在新标签页重新登录回到旧标签页面刷新后没有了刚才所有写的痕迹,我是之前被测试提过这种类似的bug,解决办法就是把信息短暂的存在了会话存储,回来刷新后再取。但这种全部页面都这样搞太夸张了,询问组长后决定以后这种情况不归为bug。
结局
最终采用第二种解决方法,完美解决了问题。
后续
这种改动影响的范围太多了,出了不少bug,大多是老缓存没有及时清理造成的
需要注意:
1、路由前置守卫加上只要是去登录页就清一遍缓存
2、app.vue里判断没有本地缓存或data里的用户信息没拿到就用reload方法刷新页面(Ctrl+f5的效果)不走缓存
3、切换登录人后跳转页面后刷新页面保证对比不出错,有的webpack版本有一个避免跳重复页面(相同路径)的校验会导致报错,这个时候就判断如果要跳的页面就是当前页面,就直接刷新
if(this.$route.path==ulLi[0].url){
window.location.reload(true);
}else{
this.$router.replace(url).then(() => {
// 重新刷新页面
location.reload()
});