有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() // 默認跳轉 } }