微信小程序阻止或监听手机返回上一个界面,返回上页前弹出询问对话框

12,519 阅读3分钟

前言

本文主要解决在微信小程序端,监听页面返回事件,包括左上角导航栏的返回键、左右滑动手势返回、安卓物理键返回、调用 navigateBack 接口返回时,弹出询问对话框。

使用page-container实现。

本人项目为小程序原生开发,如果是小程序框架,同理亦可参考。

一、需求

实现拦截页面返回,返回上一页前弹出询问对话框

背景:最近做小程序开发的项目,有一个页面,在返回上一个页面时,要提示用户“是否确定返回?”,是的话,就返回上一页;否的话,则继续留在当前页。
这个返回操作,就需要包括:左上角导航栏的返回键、左右滑动手势返回、安卓物理键返回、调用 navigateBack 接口返回。

二、实现思路

  1. 起初准备用wx.enableAlertBeforeUnload(),参考官网文档wx.enableAlertBeforeUnload()

image.png

此方法虽然简单方便,而且也不会有背景遮盖住当前页面,但是它只对左上角导航栏的返回键有效果,其他方式的返回无法触发此方法。

效果图:

image.png

代码也很简单:

onLoad: function (options) {
    wx.enableAlertBeforeUnload({
      message:"您确定要返回上一页吗?",
      success: function(res) {
        console.log("成功", res);
      },
      fail:function(errMsg) {
        console.log("失败", errMsg);
      }
    })
}

值得注意的是:此方法需要在onLoad()中使用才会在返回的时候有弹窗。

  1. 上一个方法显然不能满足我的需求,于是找到了page-container,显然正是我所需要的!参考官方文档page-container

image.png

三、实现方法

page-container是一个类似弹窗的组件,我们可以自定义返回框,而且所有类型的返回操作都能被监听。

实现步骤:

  1. 页面的最外层,用page-container包起来,在page-container的外层要写一个view,用来写wx:if,这一点很重要:

image.png

<view wx:if="{{isShow}}">
    <page-container show="{{isShow}}" overlay="{{false}}" custom-style="height:100vh;overflow:scroll" bindbeforeleave="onBeforeLeave">
        <view class="examPage">
          // 页面内容
        </view>
    </page-container>
</view>

我这边使用到的属性有如下几个,可根据实际项目需求自行定义:

image.png

备注:其中custom-style="height:100vh;overflow:scroll"是用来解决该页面内容无法上下滚动的问题。

  1. data中声明一个变量isShow,初始化时默认值为true
data() {
  isShow: true, // 最开始设置为显示
}
  1. 我们需要用到的一个事件是bind:beforeleave(离开前触发)

image.png

image.png

效果图:

image.png

  // 离开页面前触发
  onBeforeLeave(res) {
    const that = this;
    that.setData({
      isShow: false, // 先false
    });
    wx.showModal({
      title: '确认要退出吗?',
      content: '请确认答题完成,是否现在交卷?',
      success: function (res) {
        if (res.confirm) {
          wx.navigateBack() // 返回上一页
        } else if (res.cancel) {
          that.setData({
            isShow: true, // 点取消,重新展示该页面
          });
        }
      }
    })
  }

以上是所有的实现代码,可直接复制粘贴使用。

四、总结

每次小程序项目的迭代都会给我带来新的体验和感受,比如说,本来以为它不会支持的功能,试着试着竟然也能实现,就像这个返回,我本以为只有自定义导航栏才能实现,那我可就要大改了,没想到只要在页面外层套个标签就完成了。

不过这次有个优化点存在,就是这个弹窗出现后,已经设置了overlay="{{false}}",为什么下面的遮罩层还会存在呢?我想要wx.enableAlertBeforeUnload()的那种弹窗效果。希望大佬指点一下🙏!

以上,希望对大家有帮助!