Skip to content
On this page

首次点击回退关闭弹层,再次点击真正回退

适用范围

  1. 具有物理回退键或虚拟回退键的手机。

  2. 有弹层的页面不能是 Webview 着陆页。

DEMO

首次点击回退关闭弹层,再次点击真正回退 - 技术演示

原理

在页面的beforeRouteLeave周期内判断页面有无弹层,有的话先关闭弹层,并执行next(false)

根据官方手册,next(false)的作用是中断当前的导航。如果 Webview 的 URL 改变了 (可能是用户手动或者 Webview 后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

着陆页难题

如果有弹层的页面是 Webview 的着陆页,则回退之后,可能进入了空白页,也可能 Webview 关闭,所以,如果在着陆页打开弹层,而且用户打算利用回退键关闭弹层,则用户会看到意外的结果。

解决这个难题需要监听 Webview 的回退按键事件,本手册暂不讨论这种情况。

部署

如果是数据控制弹层开启、关闭

使用数据去控制弹层的显隐是常见情况,你可以仿照这样的代码:

js
export default {
  data() {
    return {
      dialogShow: false,
    };
  },
  beforeRouteLeave(to, from, next) {
    if (this.dialogShow) {
      this.dialogShow = false;
      next(false);
      return;
    }
    next();
  },
  methods: {
    onOpenDialog() {
      this.dialogShow = true;
    },
  },
};

如果是编程式创建、关闭弹层

如果是以 Vant 的 Dialog 组件为代表的编程式创建弹层,则需要编程式关闭弹层,你可以仿照这样的代码:

js
let dialogInstance;
export default {
  beforeRouteLeave(to, from, next) {
    if (dialogInstance) {
      dialogInstance = null;
      next(false);
      return;
    }
    next();
  },
  methods: {
    onOpenDialog() {
      dialogInstance = this.$dialog.alert({
        message: '弹窗内容',
        beforeClose(action, done) {
          dialogInstance = null;
          done();
        },
      });
    },
  },
};

杨亮的前端解决方案