【vue-router②】使用導航守衛控制頁面前進刷新,後退緩存

以前給你們分享了利用keep-alive進行緩存你想要的頁面,而後到後面會出現這樣的問題:
我有三個組件A(組件)、B(A中的彈框)、C(組件),其實算是兩個組件,一個彈框,如今他們的關係是這樣的:
點擊A(li循環列表組件)中某個功能,彈出了B(彈框-表格),而後在B(彈框)點擊鏈接跳轉到C(組件)。
而後我想要實現A(li循環列表組件)緩存,B(彈框-表格)根據A的傳參實時刷新,C(組件)根據B的傳參實時刷新,A->B->C。
接下來返回依次從C->B->A,以下圖:html

clipboard.png

一、B是一個彈框,和A處於同一個組件,從C返回要看到B的話,就要實現A緩存,即C返回A的時候A沒刷新還保持彈框不變就能夠實現C是退回B,這個用前面說的keep-alive就能夠實現。
二、這時候從B->A(咱們這邊退回按鈕設置關閉彈框是能夠實現B->A的),點擊的是瀏覽器或者手機的回退鍵,就會發現,並無實現這一步,而是B直接退到A的前一頁,由於系統的回退鍵記錄的是歷史路由,而B和A自己就是一個路由,因此就會出現這種狀況。
這時候的解決辦法就是:判斷路由離開前,B彈框是否打開,如果打開就先關閉彈框,不容許路由跳轉,因此就能夠形成B回退到A的假象。這時候利用的是beforeRouteLeave鉤子。實現以下:vue

beforeRouteLeave(to,from,next) {
    //B是B彈框的v-model值
    if (this.B) {
      this.B= false;
      next(false);
    } else {
      next();
    }
}

三、而後接下來你就會發現另外一個問題,就是B->C的時候,由於B是打開的,上面的判斷就會形成B沒法跳轉到C,可是沒設置上面的代碼,就會形成C回退的時候,要麼是到C->A(A不設緩存,實時刷新)->A前面的頁面,要麼C->B(A設緩存,不刷新就保持B)->A前面的頁面,不管是那種狀況都不是咱們想要的。
解決:仍是使用beforeRouteLeave,再加一層判斷,當路由跳轉的目標是C的時候,next設爲true,如果其餘跳轉則設爲false。
(1)判斷目標路由是C的時候,保持B爲true,這樣C->B,
(2)當B後退的時候,判斷B打開,則先關閉B,不後退,這樣就能B->A
(3)A再回退的時候,B已經爲false,所A就能夠再返回到它的上一級。segmentfault

beforeRouteLeave(to,from,next) {
      /*to:目標路由
      * from:當前要離開的路由
      * */
      if(to.name === "C"){
        if(this.B){
          this.B= true;
          next();
        } else{
          next();}
      }else {
        if (this.B) {
          this.B= false;
          next(false);
        } else {
          next();
        }
      }
    },

這裏就能夠實現我要的回退順序及效果。瀏覽器

說到beforeRouteLeave,就不得不跟你們提一下v-router的導航守衛,可參考官方文檔
如今我來講下我對於組件內的守衛的一個理解。共有三個:緩存

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對應路由被 confirm 前調用
    // 不!能!獲取組件實例 `this`
    // 由於當守衛執行前,組件實例還沒被建立
  },
  beforeRouteUpdate (to, from, next) {
    // 在當前路由改變,可是該組件被複用時調用
    // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。
    // 能夠訪問組件實例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 導航離開該組件的對應路由時調用
    // 能夠訪問組件實例 `this`
  }
}

三者都能接收三種參數:to, from, next函數

clipboard.png

顧名思義,
beforeRouteEnter :表示在進入當前組件前的一個操做,它執行順序是很靠前的,而其中next的回調勾子的函數,執行則很是靠後,在mounted以後!!
咱們一般是在beforeRouteEnter中加載一些首屏用數據,待數據收到後,再調用next勾子,經過回調的參數vm將數據綁定到實例上。
所以,請注意next的勾子是很是靠後的。fetch

beforeRouteEnter(to, from, next) {
    next(vm => {
        if(to.name == '目標路由名稱'){
            //vm.fetchData()
        }else{
            //vm.fetchData()
        }
    })
}

beforeRouteUpdate :表示在當前組件改變以前,這個還沒用過,具體我也不太清楚裏面的狀況,後面用到再作介紹。
beforeRouteLeave :表示在當前組件離開以前,這個就是個人最愛了,如今對於組件的狀態控制,我可都是依賴它的,像上面提到的控制彈框和跳轉。this

相關文章
相關標籤/搜索