完整代码如下:
mounted(){
// 监听手机物理返回按钮
var that = this;
if (window.history && window.history.pushState) {//监听手机的物理返回按键
history.pushState(null, null, location.href);
window.addEventListener("popstate", that.goBack2, false); //false阻止默认事件
}
document.addEventListener('visibilitychange', this.handleVisibilityChange);//监听手机息屏/亮屏
},
beforeDestroy(){
window.removeEventListener('popstate', this.goBack2, false);//false阻止默认事件
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
},
methods:{
handleVisibilityChange(){
if (document.visibilityState === 'hidden'){//visible 亮屏;hidden 息屏
this.isDestroy = true
}else{
var st = setTimeout(() => {
this.isDestroy = false
clearTimeout(st)
}, 500);
}
},
// 手机物理按钮返回监听事件(处理业务逻辑)
goBack2(){
if(this.isDestroy){//手机息屏后,再亮屏,由于监听事件,会执行一次 goBack2 方法,这里是阻止在亮屏的时候,执行返回操作
return
}
// window.history.forward()//在点击后退键后,手动让它回到下一页。这种会出现页面闪屏
const state = {
key: Math.random() * new Date().getTime()
}
if(this.step2DetailFlag){
this.step2DetailFlag = false
window.history.pushState(state, null, location.href)
}else if(this.step3DetailFlag){
this.step3DetailFlag = false
window.history.pushState(state, null, location.href)
}else if(this.step4PlanFlag){
this.step4PlanFlag = false
}else if(this.detailFlag && !this.historyFlag){
this.$router.back();
}else if(this.detailFlag && this.historyFlag){
this.detailFlag = false
window.history.pushState(state, null, location.href)
}else if(!this.detailFlag && this.historyFlag){
this.historyFlag = false
window.history.pushState(state, null, location.href)
}else{
this.$router.back();
}
},
}
因为该页面使用的popstate监听手机物理返回按钮,当手机息屏后,再次亮屏时,会默认自动执行一次goBack2方法,会造成业务逻辑混乱。
所以,在mounted的时候,添加手机息屏、亮屏的监听事件visibilitychange,当息屏时,改变isDestroy的状态值为true。在亮屏时,因为页面会自动执行goBack2方法,所以在此方法中判断isDestroy的值,若为true时,则不会再执行后面的业务逻辑。在监听到亮屏后,再使用setTimeout延迟函数,将isDestroy的值改为false,这样就不会印象页面的整体业务逻辑了。