vue-router 一些容易被忽略的知識點

shoyuf_發表於2019-03-02

本文適用於對 Vue.js 和 vue-router 有一定程度瞭解的開發者

除特殊說明,vue-router 版本為 3.0.2

正文

  • 路由 class 匹配

    <router-link> 路由匹配後會給該標籤新增 class 屬性值 .router-link-active,該功能在巢狀路由中十分方便

    class 的實際屬性值可以通過 的 active-class 來控制,全域性預設值則通過路由構造選項 linkActiveClass 來控制

    預設情況下,當前路由的所有父級會預設新增 active-class ,即 當前處於/user/1 會給當前頁面的 <router-link to="/"> 新增 active-class ,如果不需要此項,給 <router-link> 新增 exact 即可,精準匹配的 class 通過 exact-active-class 控制

    示例:JSFiddle

  • 萬用字元路由

    路由配置: {path: `/user-*`} ,訪問 /user-admin 路由,可在 $route.params.pathMatch 獲取到 `admin` (pathMatch 僅在 vue-router@3.0.2+ 可用,低於此版本使用 $route.params[0] 嘗試獲取)

    示例:JSFiddle

    文件:捕獲所有路由或 404 Not found 路由

  • 路由高階匹配模式

    vue-router 使用 path-to-regexp 作為路由匹配引擎,該庫可以通過輸入的路徑生成匹配規則的正規表示式,從而實現路由匹配功能。

    path-to-regexp 中常用的方法 pathToRegexp(path, keys, options) 第三個引數為 pathToRegexpOptions 編譯正則的選項,在 vue-router@2.6.0+ 版本可以通過配置 routepathToRegexpOptions 引數新增高階配選項。

    參考例子,其可通過 `/optional-params/:foo?` 實現可選 param ,也可通過 `/params-with-regex/:id(\d+)` 實現僅匹配數字 param(非命中路由向後匹配)。

    pathToRegexpOptions 的內容為:

    • sensitive 大小寫敏感 (default: false)
    • strict 末尾斜槓是否精確匹配 (default: false)
    • end 全域性匹配 (default: true)
    • start 從開始位置展開匹配 (default: true)
    • delimiter 指定其他分隔符 (default: `/`)
    • endsWith 指定標準的結束字元
    • whitelist 指定分隔符列表 (default: undefined, any character)

    原始碼:vue-router/src/create-route-map.js:154
    文件:高階匹配模式

  • 程式設計式導航的鉤子處理

    vue-router@2.2.0+,可選的在 router.pushrouter.replace 中提供 onCompleteonAbort 回撥作為第二個和第三個引數。這些回撥將會在導航成功完成 (在所有的非同步鉤子被解析之後) 或終止 (導航到相同的路由、或在當前導航完成之前導航到另一個不同的路由) 的時候進行相應的呼叫。
    該功能可用在少數埋點場景,而不用配置複雜的路由鉤子。

  • 路由重定向

    route 配置 redirect 屬性可使路由重定向到指定路由,該屬性支援 String/Object/Function 三種型別的值,其中 Function 的引數為 to 物件

    給重定向的中間路由新增 beforeEachbeforeLeave 不會有效果,給 router 新增的鉤子也不能檢測到此次重定向,如果需要判斷重定向來源,可使用路由物件 $route.redirectedFrom 判斷

    該功能適合路由 path 修改後保留原路由的重定向

    文件:重定向

  • 巢狀命名檢視

    在平級展示多個檢視時(單個檢視使用多個平級的<router-view>),可以用到 <router-view>name prop
    例如在 sidebar/list 的佈局頁面上,不用在父級檢視容器去書寫許多子元件的邏輯,只需要在路由配置中配置好相關頁面元件,從而進行元件關係解耦,也能高效控制子檢視渲染

    例子:JSFiddle

    文件:巢狀命名檢視

  • 路由別名

    route 配置 alias 屬性可以使訪問者保持原有 url 卻訪問到指定路由中去。

    該屬性支援 StringArray 兩種型別,當 alias 與其他路由重複時,以先申明的路由為準,同時別名不會進行路由 class 匹配

    文件:別名

  • 路由元件傳參

    該功能旨在給元件與路由解除耦合關係,給 route 配置 props: true 同時元件內 props 配置與 prams 相同的變數,可以直接通過訪問 props 而不用通過 $route.params 去訪問引數

    如果 props 是一個物件,物件內容會當作靜態內容傳入元件作為 props

    props 為一個函式,函式接收一個 route 引數,可以使 query 作為 props 傳入元件或實現更多高階功能

    文件:路由元件傳參

  • 完整的導航解析流程

    1. 導航被觸發。
    2. 在失活的元件裡呼叫離開守衛。
    3. 呼叫全域性的 beforeEach 守衛。
    4. 在重用的元件裡呼叫 beforeRouteUpdate 守衛 (vue-router@2.2+)。
    5. 在路由配置裡呼叫 beforeEnter。
    6. 解析非同步路由元件。
    7. 在被啟用的元件裡呼叫 beforeRouteEnter。
    8. 呼叫全域性的 beforeResolve 守衛 (vue-router@2.5+)。
    9. 導航被確認。
    10. 呼叫全域性的 afterEach 鉤子。
    11. 觸發 DOM 更新。
    12. 用建立好的例項呼叫 beforeRouteEnter 守衛中傳給 next 的回撥函式。

    文件:完整的導航解析流程

  • 滾動行為

    建立 Router 例項,可以提供一個 scrollBehavior 方法,該方法接收 tofromsavedPosition(該頁面原存在的xy值,僅在通過瀏覽器前進後退中可用)

    在該方法中返回 {selector:to.hash} 還可實現類似於“滾動到錨點”的行為,vue-router@2.6.0+ 還可返回 {offset?:{x,y}} 進行位置偏移,注意該偏移負值為向負方向偏移

    非同步滾動 通常用於小眾的過渡元件(transition)和滾動行為同時進行的情況下,官方例項未給太多相關資訊

    文件:滾動行為

  • 元件懶載入-按組分塊

    SPA(single page application)由於 All in JS 的特性,會使得首屏載入比較慢,很多人都推薦使用 Webpack 的 程式碼分割功能減小單個 JS 體積,當所有頁面元件使用動態載入則會使頁面請求過多而得不償失,所以元件按組分塊則應運而生:

      const Foo = () => import(/* webpackChunkName: "group-foo" */ `./Foo.vue`)
      const Bar = () => import(/* webpackChunkName: "group-foo" */ `./Bar.vue`)
      const Baz = () => import(/* webpackChunkName: "group-foo" */ `./Baz.vue`)
    複製程式碼

    該功能需要 webpack@2.4+ 支援

    文件:把元件按組分塊

  • 獲取路由匹配元件

    router.getMatchedComponents(location?)

    該函式可以獲取傳入引數在路由表中匹配的路由物件陣列,官方文件中寫到通常在服務端渲染資料預載入的時候,也可用於在獲取當前路由物件陣列的時候

    如果需要獲取當前路由記錄(就是路由構造選項 routes 配置陣列中的物件副本,包含children 陣列),可用 route.matched

    文件:getMatchedComponents
    文件:$route.matched

  • 解析路由

    router.resolve(location, current?, append?)

    該函式可同時匯出一個類似瀏覽器的 location 物件和一個根據匹配到的路由記錄 resolved ,如果沒有匹配到對應的物件,resolved 欄位預設返回 404 元件或錯誤資料

    文件:router.resolve

  • 新增路由

    router.addRoutes(routes:Array<RouteConfig>)

    該函式可以使用者觸發新增路由到路由表中,可以嘗試在使用者許可權控制中使用

    文件:router.addRoutes

建議

  • 簡單按鈕的路由跳轉邏輯不使用 v-on:click 事件,多使用 <router-link> 標籤。

  • 如果 SPA 放置路徑處於域名的子目錄中,不要按照一些網路教程寫的去修改 webpack 配置,應該修改 Router 構建選項 中的 base 值,這樣能避免一些不必要的問題

  • 不要嘗試改變元件內的 $route 的內容,這個屬性是隻讀,裡面的屬性是 immutable 狀態,但你可以 watch 這個

參考資料

  1. url 的正規表示式:path-to-regexp – 簡書
  2. vue-router Document
  3. vue-router Source Code

本文首發地址

blog.shoyuf.top

第一次在掘金上發文章,歡迎各位評論區中吐槽指正

相關文章