前端培訓-中級階段(40)- vue 2.x 路由 vue-router

前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。html

單頁應用的話,咱們主要仍是要依賴 Vue-router 來實現路由系統。今天咱們來看看 vue-router 平常使用的內容。前端

以前咱們有一些系統是用 vue-element-admin 來作的,做者寫的不錯,路由權限、動態路由權限都有現成的方案。找實現方法能夠直接看一下開源的代碼vue

vue-router 支持的特性

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌。包含的功能有:webpack

  • 嵌套的路由/視圖表
    <router-view> 嵌套,而後定義 routes 時定義 children
  • 模塊化的、基於組件的路由配置
  • 路由參數、查詢、通配符git

    • 好比動態路由:定義的時候 /user/:id,獲取的時候this.$route.params.id
    • 好比通配符 *:通常是在 router 最後定義,指向一個 404 顯示
    • 能夠獲取查詢字符串 $route.query,也能夠獲取錨點 $route.hash
  • 基於 Vue.js 過渡系統的視圖過渡效果
  • 細粒度的導航控制
  • 帶有自動激活的 CSS class 的連接
  • HTML5 歷史模式或 hash 模式,在 IE9 中自動降級
  • 自定義的滾動條行爲

vue-router 使用

能夠運行的demo

<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 組件來導航. -->
    <!-- 經過傳入 `to` 屬性指定連接. -->
    <!-- <router-link> 默認會被渲染成一個 `<a>` 標籤 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的組件將渲染在這裏 -->
  <router-view></router-view>
</div>
<script>
// 0. 若是使用模塊化機制編程,導入Vue和VueRouter,要調用 Vue.use(VueRouter)

// 1. 定義 (路由) 組件。
// 能夠從其餘文件 import 進來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定義路由
// 每一個路由應該映射一個組件。 其中"component" 能夠是
// 經過 Vue.extend() 建立的組件構造器,
// 或者,只是一個組件配置對象。
// 咱們晚點再討論嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 建立 router 實例,而後傳 `routes` 配置
// 你還能夠傳別的配置參數, 不過先這麼簡單着吧。
const router = new VueRouter({
  routes // (縮寫) 至關於 routes: routes
})

// 4. 建立和掛載根實例。
// 記得要經過 router 配置參數注入路由,
// 從而讓整個應用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

// 如今,應用已經啓動了!
</script>

導航守衛、路由鉤子函數

提供了跳轉或取消導航的能力。分爲全局路由組件級
參數或查詢的改變並不會觸發進入/離開的導航守衛,能夠經過觀察 $route 對象來應對這些變化,或使用 beforeRouteUpdate 的組件內守衛。github

全局級別的鉤子函數

全局級別是指定義在 router 上,好比 router.beforeEachweb

  1. beforeEach 全局前置鉤子函數。當一個導航觸發時,全局前置守衛按照建立順序調用。守衛是異步解析執行,此時導航在全部守衛 resolve 完以前一直處於 等待中vue-router

    const router = new VueRouter({ ... })
    router.beforeEach((to, from, next) => {
        // to: Route: 即將要進入的目標路由對象
        // from: Route: 當前導航正要離開的路由
        // next():執行下一個鉤子,必須調用,不然會一直等待
        // next(false):中斷這次跳轉
        // next(path):跳轉到新的地址,通常是權限判斷,無權限去登錄頁
        // next(error): (2.4.0+)觸發 onError 事件
    })
  2. beforeResolve 全局解析鉤子函數 ( 2.5.0+)。這和 router.beforeEach 相似,區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,解析守衛就被調用。
  3. afterEach 全局後置鉤子函數

路由級別的鉤子函數

路由級別是指在 routes 定義時設置的。編程

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

組件級別的鉤子函數

組件級別就是指在定義組件時寫的了,和 mounted 同級。好比路由改變,可是由於組件共享問題,須要刷新這個時候咱們能夠在 beforeRouteUpdate 裏面作邏輯,或者 watch 監聽 $routesegmentfault

  • beforeRouteEnter 渲染組件前被調用,沒法獲取this
  • beforeRouteUpdate (2.2 新增) 在當前路由改變,可是該組件被複用時調用
  • beforeRouteLeave 導航離開該組件的對應路由時調用。能夠用來實現禁止用戶在還未保存修改時異常離開,提示保存內容

完整的導航解析流程

  1. 導航被觸發。
  2. 在失活的組件裏調用 beforeRouteLeave 守衛。
  3. 調用全局的 beforeEach 守衛。
  4. 在重用的組件裏調用 beforeRouteUpdate 守衛 (2.2+)。
  5. 在路由配置裏調用 beforeEnter
  6. 解析異步路由組件。
  7. 在被激活的組件裏調用 beforeRouteEnter
  8. 調用全局的 beforeResolve 守衛 (2.5+)。
  9. 導航被確認。
  10. 調用全局的 afterEach 鉤子。
  11. 觸發 DOM 更新。
  12. 調用 beforeRouteEnter 守衛中傳給 next 的回調函數,建立好的組件實例會做爲回調函數的參數傳入。

路由對象屬性 $route

下面的屬性介紹,統一都基於下面的配置:
頁面URL: https://www.lilnong.top/cors/vueRouter?a=1#b
路由規則:/cors/:key

  1. path 對應當前路由的路徑,老是解析爲絕對路徑 /cors/vueRouter
  2. params 對應路由規則中的參數。this.$route.params.key == 'vueRouter'
  3. query 對應的是查詢字符串。this.$route.query.a == '1'
  4. hash 對應的就是錨點。this.$route.hash == '#b'
  5. fullPath 對應的就是完整的URL。
  6. matched 包含的是全部匹配的路由規則。
  7. name 包含的是當前路由的name屬性
  8. redirectedFrom 對應的是重定向的來源位置。

高級技巧

  1. 組件與路由系統解耦,組件開發中咱們通常是定義 props,可是路由系統倒是 $route 這種衝突破壞了咱們組件,下降了複用性。這個時候咱們在定義 routes 時,給組件設置 props: true,這樣 route.params 將會被設置爲組件屬性。

    1. props: true:將 route.params 設置爲組件屬性
    2. props: { aaa: false }:直接將這個對象,傳進去爲組件屬性
    3. props: function:經過編程的方式生成一個對象,傳進去當組件屬性
  2. 路由攜帶入參(路由元信息 meta),有時候咱們須要給路由設置一些信息,好比是否緩存能夠訪問的角色&權限控制

    1. 定義時

      const router = new VueRouter({
        routes: [
          {
            path: '/config',
            component: config,
            meta: {role:['admin']}
          }
        ]
      })
    2. 獲取時 $route.meta.role。也能夠在鉤子函數中獲取 to.matched.map(record => record.meta.role), matched 能夠獲取到全部被匹配到的路由記錄
  3. 路由懶加載,咱們須要結合 Vue 的異步組件和 Webpack 的代碼分割功能,來實現路由組件的懶加載。
    Vue 中容許組件是異步的const Foo = () => Promise.resolve({ /* 組件定義對象 */ })
    配合 webpack 引入資源就變成了 const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') /* webpackChunkName: "group-foo" */ 是一個按組分塊打包的功能,能夠看我的是否使用了。
  4. 動態添加的路由規則router.addRoutes(routes: Array<RouteConfig>)

常見的注意項

  1. 使用路由參數時,組件會複用,複用的組件生命週期鉤子不會再次被調用。能夠經過 watch 監聽 $route 來監聽改變,也能夠經過 beforeRouteUpdate 鉤子函數(vueRouter@2.2 版本支持)。
  2. * 匹配 404 時,搭配着動態路由使用時,出現沒法響應後加的路由問題。這是由於匹配規則是先匹配前面定義的,若是找到就不會繼續匹配了(匹配的優先級就按照路由的定義順序:誰先定義的,誰的優先級就最高。)。因此解決方案就是把404匹配規則也作到動態添加里面。

微信公衆號:前端linong

clipboard.png

參考文獻

  1. 前端培訓目錄、前端培訓規劃、前端培訓計劃
相關文章
相關標籤/搜索