vue项目中监听手机物理返回键

2,608 阅读1分钟

需求: 点击头部的返回会弹出弹窗 确认 返回 还是 继续

但是对于手机默认的返回不会有作用,会直接返回上一个页面

原理:利用history 和 浏览器 刷新popstate状态去实现.

每一次返回都会去历史记录回退 -1 所以就在进入页面之前 往历史记录里面多记录一次当前页面的链接。然后再回退的时候监听刷新,去做一些事情。

碰到的问题: 手机点击了物理返回 然后又选择了继续 这时需要在添加一条历史记录

代码:

mounted () {
  // 如果支持 popstate 一般移动端都支持了
  if (window.history && window.history.pushState) {
    // 往历史记录里面添加一条新的当前页面的url
    history.pushState(null, null, document.URL);
    // 给 popstate 绑定一个方法 监听页面刷新
    window.addEventListener('popstate', this.backChange, false);//false阻止默认事件
  }
},
methods: {
  backChange() { // 手机自带返回
    // const that = this;
    this.$dialog.confirm({
      message: '你是否要退出本次考试?',
      confirmButtonText: '继续',
      confirmButtonColor: '#B92D36',
      cancelButtonText: '退出'
    })
    .then(() => {
      if (window.history && window.history.pushState) {
        // 手机点击了物理返回 然后又选择了继续 这时需要在添加一条记录
        history.pushState(null, null, document.URL)
      }
    })
    .catch(() => {
      this.$router.push({path: '/exam/fillPerson', query: { examId: this.$route.query.examId, examName: this.$route.query.examName }})
    })
  },
  onClickLeft () { // 头部返回
    // this.$router.go(-1)
    this.$dialog.confirm({
      message: '你是否要退出本次考试?',
      confirmButtonText: '继续',
      confirmButtonColor: '#B92D36',
      cancelButtonText: '退出'
    })
    .then(() => {
      // on confirm
    })
    .catch(() => {
      // this.$router.go(-1)
      this.$router.push({path: '/exam/fillPerson', query: { examId: this.$route.query.examId, examName: this.$route.query.examName }})
    })
  }
}

destroyed(){
  window.removeEventListener('popstate', this.backChange, false);//false阻止默认事件
}

参考文章