# 点击浏览器返回按钮跳转到指定页面

# 通过监听 popState

  • 活动历史记录条目更改时会触发 popState 事件,当用户点击浏览器的回退按钮或通过 js 调用 history.back()会更改历史记录条目。

WARNING

注意:

  • 通过 history.pushState()或 history.replaceState()创建历史记录条目

  • history.pushState()或 history.replaceState()不会触发 popState 事件

  • popstate 事件的 state 属性包含历史条目的状态对象的副本

  • 不同浏览器在加载页面时触发 popState 事件的不同:Chrome、Safari 会触发,Firefox 不会触发。

// 控制用户点击返回按钮,跳到指定页面
// 使用web-back,如果用动态的设置返回的路由,需要在方法中设置false,需要在method里面写入backRouterJump方法,覆盖插件中的backRouterJump

/**
 * 使用方式:
 * import webBack from 'web-back';
 * var webBackMixin = webBack({路由信息})
 *
 * mixin:[webBackMixin]
 */

export default function(route, bool = true) {
  return {
    data() {
      return {
        backState: getUUID(),
        backStateNext: getUUID(),
        backRouter: route,
        isFromBack: false,
        isDefaultBack: bool
      }
    },
    beforeRouteEnter(to, from, next) {
      next(vm => {
        vm.isFromBack = from.name === vm.backRouter.name
        vm.initBackEvent()
      })
    },
    beforeRouteLeave(to, from, next) {
      window.removeEventListener('popstate', this.back)
      next()
    },
    methods: {
      initBackEvent() {
        if (history.state !== this.backStateNext && !this.isFromBack) {
          history.replaceState(this.backState, null, location.href)
          history.pushState(this.backStateNext, null, location.href)
        }

        window.addEventListener('popstate', this.back)
      },
      back(ev) {
        if (ev.state === this.backState) {
          if (this.isDefaultBack) {
            this.$router.replace(this.backRouter)
          } else {
            this.backRouterJump(this.backRouter)
          }
        }
      },
      backRouterJump(route) {
        this.$router.replace(route)
      }
    }
  }
}

function getUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = (Math.random() * 16) | 0,
      v = c == 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

参考资料: popState 事件