學習筆記《vue-router》

weixin_34290000發表於2017-04-22

使用 Vue 做 SPA 實現的時候,路由系統是無法繞過的一個重要子系統:

  • 使用路由系統對頁面進行模組化
  • 對瀏覽器的 History API 進行封裝,構建良好的使用者體驗
  • 藉助路由的呼叫,作為響應式程式設計的發起端
  • 路由的巢狀關係,可以很好的展示出路由的結構關係

Vue 的路由系統分三種模式

  1. hash模式: 使用 URL hash 值來作路由。預設模式
  2. history模式: 依賴 HTML5 History API 和伺服器配置
  3. abstract模式: 適用於客戶端,移動端的抽象呼叫機制

為了在使用單頁面應用的時候,瀏覽器的「前進」和「後退」可以依然有效,需要通過呼叫 Vue Router 提供的方法進行頁面跳轉:

// HTML 中
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

// JS 中
router.push({ name: 'user', params: { userId: 123 }})
  • type: string
  • default: "hash" (in browser) | "abstract" (in Node.js)
  • available values: "hash" | "history" | "abstract"
    Configure the router mode.
    • hash: uses the URL hash for routing. Works in all Vue-supported browsers, including those that do not support HTML5 History API.
    • history: requires HTML5 History API and server config. See
      HTML5 History Mode.
    • abstract: works in all JavaScript environments, e.g. server-side with Node.js. The router will automatically be forced into this mode if no browser API is present.

從三種模式的介紹中也可以看出來,客戶端環境中只支援使用 abstract 模式。vue-router 自身會對環境做校驗,如果發現沒有瀏覽器的 API,vue-router 會自動強制進入 abstract 模式,所以在使用時只要不寫 mode 配置即可。預設 vue-router 會在瀏覽器環境中使用 hash 模式,在移動端原生環境中使用 abstract 模式。

瀏覽器的 History API 詳情:
https://developer.mozilla.org/en-US/docs/Web/API/History_API

在 console 中除錯

我在 Vue 的 app.js 的最後新增這麼一段程式碼,協助在 console 中除錯:

Vue.router = router; // 可以在chrome裡面使用 Vue.router.go(-1) 類似的方法來進行除錯

路由的巢狀

在我看來,展示出結構性上的特徵可以大大的提高程式碼的可閱讀性和程式的整體設計思路,所以具有可巢狀的路由結構是一種非常優雅的設計

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // UserProfile will be rendered inside User's <router-view>
          // when /user/:id/profile is matched
          path: 'profile',
          component: UserProfile
        },
        {
          // UserPosts will be rendered inside User's <router-view>
          // when /user/:id/posts is matched
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

路由的 name屬性

路由的 name屬性 最主要的價值是對路由的設計進行解耦,方便做結構性上的調整,所以每一條路由都有一個 name 是非常重要的

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

路由的 props屬性

路由的 props屬性 也是為了解耦而設計的,通過路由將路由中的引數值傳給到 components 裡面,方便 components 的其他部分呼叫

不推薦的引數使用方式:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})

推薦的引數使用方式:

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true }

    // for routes with named views, you have to define the props option for each named view:
    {
      path: '/user/:id', 
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

Navigation Guards

這是一個類似 Laravel Middleware 的機制,可以對路由訪問的進出過程進行控制,方便對所有路由進行統一的功能性處理,有一個印度人做了一個視訊,講解的非常清楚:
《#5 Vue.js 2.0 and Router guard - authenticating Vue.js routes - Vue.js 2.0 and Laravel 5.3》

官方文件裡面提供了一個例子的展示,非常一目瞭然:
https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js

懶載入

為了減少每個檔案的大小,Vue Router 有一種懶載入的機制:
https://router.vuejs.org/en/advanced/lazy-loading.html

其他

後面的東西比較遠了,等深度時候到的時候再補充

相關文章