vue指定返回键的路由(点击浏览器的返回按钮/beforeRouterLeave)


有A、B、C三个页面,跳转顺序为A-->B-->C-->B-->A

从A进入B,再从B进入C,从C返回到B,此时,点击浏览器的返回按钮,需要回到A,但是却到达了C

这个过程的路由栈为A --> B --> C --> B,此时点击浏览器的返回按钮,铁定是返回C了

解决办法:

第一种方法:B中监听浏览器返回按钮

  mounted() {
    if (window.history && window.history.pushState) {
      history.pushState(null, null, document.URL)
      window.addEventListener('popstate', this.back)
    }
  },
  destroyed() {
    window.removeEventListener('popstate', this.back)
  },
  methods: {
    back() {
      this.$router.push({ name: 'A' })
    }
  }

第二种方法:C中返回到B时,不要使用push,改用go(-1)或back()

this.$router.go(-1)

此时的路由栈为 A --> B,所以在B中点击浏览器的返回按钮,就会返回到A

question:为什么不用replace?

  C中使用replace返回,本质上是用B替换了C页面,此时页面显示的是B,但是路由栈中路由停留在C。

  此时点击返回按钮需要点2次才能回到A。第一次点返回,是C到B,因为页面此时已经显示B,所以没有反应;第二次点返回,才是B到A

第三种方法:beforeRouterLeave(有些情况下,必须要使用push跳转,第二种方法就不适用了)

  场景:从【 A列表】跳转至【B新增】,新增成功后跳转至【B列表】,此时就不能用go(-1)了

  data() {
    return {
      fromRouterName: '' // 定义一个全局变量,存储上一个URL(C)
    }
  },
  beforeRouteEnter(to, from, next) {
    next(vm => {
      vm.fromRouterName = from.name // 进入该页面时,记录上一个URL(C)----此钩子在created前执行,获取不到this,所以要使用vm
    })
  },
  beforeRouteLeave(to, from, next) {
    if (this.fromRouterName === 'C' && to.name === 'C') { // 如果是由C返回的,又进入到C这种情况,跳转至A
      next({ name: 'A' })
    } else {
      next() // 默认跳转
    }
  }