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