1. 程式人生 > 實用技巧 >Vue-router前端路由(2)

Vue-router前端路由(2)

Vue-router前端路由(2)

Vue-router全域性導航守衛:

為什麼使用導航守衛:(修改網頁標題)

  • 網頁標題是通過title來顯示的,但SPA只有一個固定的HTML,切換元件無法修改title
  • 但我們可以通過JavaScript來修改title的內容:document.title
  • 這時就需要用到我們的導航守衛來實現這個動態修改

router.beforeEach函式的使用:

router.beforeEach()本身需要一個引數,從原始碼中可知該引數是一個函式

beforeEach(guard: NavigationGuard): Function

從原始碼中解讀該guard函式本身同樣包含三個引數(to, from, next)

export type NavigationGuard<V extends Vue = Vue> = (
  to: Route,
  from: Route,
  next: NavigationGuardNext<V>
) => any

同時引數next本身又是一個函式:

export type NavigationGuardNext<V extends Vue = Vue> = (
  to?: RawLocation | false | ((vm: V) => any) | void
) => void

另兩個引數to和from的含義就是:從我們的from跳轉到to,在這個跳轉過程中便可實行我們改變title的操作。

to:即將要進入的目標的路由物件

from:當前導航即將要離開的路由物件

next:呼叫該方法後,才能進入下一個鉤子

我們要做的是將頁面title賦值為需要跳轉到的介面to的title,然而to裡面沒有title這個屬性,這時候我們再回到原始碼,發現to是一個route型別,而route型別就是router物件中的一個個路由對映,所以我們可以給每個路由對映里加上一個meta(元資料)屬性,裡面給上頁面元件title

router.beforeEach((to, from, next) => {
  document.title = to.meta.title
  next()
})

然而當存在路由巢狀時,我們的to就會出現問題,因為巢狀的子路由並沒有給它meta元資料,這時除了給子路由加上meta以外,還有另一個方法取得主路由的meta。

從下圖可以發現,在當前to物件中meta屬性是空的,但是在matched(物件陣列)屬性下的第一個物件matched[0]中,儲存著我們主路由的meta,所以我們可以修改一下程式碼。來保證獲取到當前頁面的title。

router.beforeEach((to, from, next) => {
  document.title = to.matched[0].meta.title;
  console.log(to);
  next();
})

之前我們所討論的是router導航守衛的前置守衛(guard)beforeEach,接下來我們來討論一下後置鉤子(hook)afterEach

前置守衛是在路由跳轉前回調,後置鉤子則是路由跳轉後回撥

這是後置鉤子的原始碼:(不含next函式)

afterEach(hook: (to: Route, from: Route) => any): Function

後置鉤子的呼叫:

router.afterEach( (to, from) => {
  console.log('---');
  console.log(to);
  console.log(from);
})

我們上面是用的導航守衛被稱之為全域性守衛

  • 路由獨享守衛
  • 元件內的守衛

Vue-router-keep-alive

keep-alive是Vue內建的一個元件,可以使被包含的元件保留狀態,或避免重新渲染。

route-view也是一個元件,如果直接被包在keep-alive裡面,所有的路徑匹配到的檢視元件都會被快取

activated和deactivated函式只有元件在keep-alive的情況下可以被呼叫

keep-alive兩個重要的屬性:

  • include - 字串或正則表示式,只有匹配的元件會被快取
  • exclude - 字串或正則表示式,任何匹配的元件不會被快取

*注:像exclude="profile,user"的寫法,逗號後面不能加空格!!