vue项目,运行在微信公众号,测试ios设备的时候发现从数据总览页点击一个新的页面,执行部分操作后,总览页面的数据应该被修改的,但是点击返回只会,总览页面还是旧数据,手动点击刷新之后数据才被修正。
这是部分浏览器的特性,back-forware-cache,部分浏览器前往另一个页面之前会缓存本页面的锚点和页面数据和js执行状态,从另一个页面返回的时候只是从缓存中加载上一个页面的数据。不会触发页面加载的事件。
网络上有监听pageshow和pagehide的方案。但是测试之后发现,pageshow的确会触发,但是pagehide并没有触发,也就不能实现效果,于是想到了以前监听的pushstate和popstate。知道是返回事件后,判断当前是不是ios设备,是不是需要刷新的页面。
import { MessageBox, Toast } from 'mint-ui';class CommonUtils{install(Vue){Vue.prototype.CommonUtils = thisthis.pageEventOk = falsethis.handleBackForwardCache()}getDeviceType(){var u = navigator.userAgent, app = navigator.appVersion;var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //gvar isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端if (isAndroid) {return "android";}if (isIOS) {return "ios";}}handleBackForwardCache(){if(this.pageEventOk){return}this.pageEventOk = true// console.log("add event listener, popstate")window.addEventListener('popstate', ()=>{// Toast("popstate:" + window.location.pathname)// Toast("popstate:" + document.referrer)// 检查是不是需要显示最新数据的页面if(window.location.pathname.endsWith("/shop/database")){// 检查是不是ios设备if(this.getDeviceType() == "ios"){// ios页面返回的时候,可能显示的是缓存页面// 刷新window.location = document.referrer}}})}
}export default new CommonUtils
用单例模式防止方法被重复调用,加个变量pageEventOk方式事件被重复监听。
不是所有页面都需要做这种操作,所以最好还是判断试下当前页面。
还有一种做法是从关键页面跳转的时候不用go、pushstate,不用$router.psh,这样浏览器点击返回的时候就不会返回关键页面。自己做一个返回按钮,点击按钮的时候不用 $router.go(-1),直接用$router.push或者$router.replace。这样就可以欺骗浏览器。