vue-router用法記錄

Vue-Router簡介

Vue-Router是Vue.js官方維護的路由插件,同時也是官方推薦的路由插件。它與Vue.js內核深度結合,讓開發單頁應用更加容易簡便。

基本配置

  • **HTML **

<router-link> 對應的路由匹配成功,將自動設置 class 屬性值 .router-link-active

<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>
  • JavaScript
Vue.use(VueRouter)

//定義路由
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

//創建router實例
const router = new VueRouter({
  routes // (縮寫)相當于 routes: routes
})

//掛載實例
const app = new Vue({
  router
}).$mount('#app')

動態路由配置

  • 場景:通過URL傳遞參數

    const router = new VueRouter({
      routes: [
        // 動態路徑參數 以冒號開頭
        { path: '/user/:id', component: User }
      ]
    })
    

    動態路徑參數使用冒號:標記,對應的值都會設置到 $route.params中。此處可通過this.$route.params.id來獲取id,在模板中可以省略this.,如

    const User = {
      template: '<div>User {{ $route.params.id }}</div>'
    }
    
  • 如果是非必須的參數,可在參數后加一個?,如path:''/page1/:id?'對于帶查詢參數的URL,如 /page1?id=123可用 $route.query 訪問,如果沒有查詢參數,則是個空對象。

響應路由參數的變化

當使用路由參數時,例如從 /page1/123 導航到 /page1/321,原來的組件實例會被復用。因為兩個路由都渲染同個組件,比起銷毀再創建,復用則顯得更加高效。不過,這也意味著組件的生命周期鉤子不會再被調用。

復用組件時,想對路由參數的變化作出響應的話,你可以簡單地watch(監測變化) $route 對象。

watch: {
  '$route' (to, from) {
    // 對路由變化作出響應...
  }
}

或者使用 2.2 中引入的 beforeRouteUpdate 守衛:

beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }

嵌套路由

實際生活中的應用界面,通常由多層嵌套的組件組合而成。同樣地,URL 中各段動態路徑也按某種結構對應嵌套的各層組件。借助 vue-router,使用嵌套路由配置,就可以很簡單地表達這種關系。

使用 children 配置

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // 當 /user/:id/profile 匹配成功,
          // UserProfile 會被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 當 /user/:id/posts 匹配成功
          // UserPosts 會被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

編程式導航

除了使用 <router-link> 創建a 標簽來定義導航鏈接,我們還可以借助router 的實例方法,通過編寫代碼來實現。

// 字符串
router.push('home')

// 對象
router.push({ path: 'home' })

// 命名的路由-> /user/123
router.push({ name: 'user', params: { userId: 123 }})

// 帶查詢參數,變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 path,params 會被忽略

const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 這里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

命名路由

有時候,通過一個名稱來標識一個路由顯得更方便一些,特別是在鏈接一個路由,或者是執行一些跳轉的時候。命名路由可以通過$route.name來獲取名稱。

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

路由元信息

定義路由的時候可以配置meta 字段。可通過$route.meta訪問。

{
   path: '/user/:userId',
   name: 'user',
   component: User,
   meta: {
     title: 'user'
   }
}

全局鉤子和路由獨享的鉤子

正如其名,vue-router 提供的導航守衛主要用來通過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程中:全局的, 單個路由獨享的, 或者組件級的。

記住參數或查詢的改變并不會觸發進入/離開的導航守衛。你可以通過觀察 $route 對象來應對這些變化,或使用 beforeRouteUpdate 的組件內守衛。

  • 全局守衛

    你可以使用 router.beforeEach 注冊一個全局前置守衛:

    const router = new VueRouter({ ... })
    router.beforeEach((to, from, next) => {
      // ...
    })
    

    當一個導航觸發時,全局前置守衛按照創建順序調用。守衛是異步解析執行,此時導航在所有守衛 resolve 完之前一直處于 等待中

    每個守衛方法接收三個參數:

    • to: Route: 即將要進入的目標 路由對象
    • from: Route: 當前導航正要離開的路由
    • next: Function: 一定要調用該方法來 resolve 這個鉤子。執行效果依賴 next 方法的調用參數。
      • next(): 進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是 confirmed (確認的)。
      • next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了(可能是用戶手動或者瀏覽器后退按鈕),那么 URL 地址會重置到 from 路由對應的地址。
      • next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。
      • next(error): (2.4.0+) 如果傳入 next 的參數是一個 Error 實例,則導航會被終止且該錯誤會被傳遞給 router.onError() 注冊過的回調。

    確保要調用 next 方法,否則鉤子就不會被 resolved。

  • 全局解析守衛

    在 2.5.0+ 你可以用 router.beforeResolve 注冊一個全局守衛。這和 router.beforeEach 類似,區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用。

  • 全局后置鉤子

    你也可以注冊全局后置鉤子,然而和守衛不同的是,這些鉤子不會接受 next 函數也不會改變導航本身:

    router.afterEach((to, from) => {
      // ...
    })
    
  • 路由獨享的守衛

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            // ...
          }
        }
      ]
    })
    
  • 組件內的守衛

    最后,你可以在路由組件內直接定義以下路由導航守衛:

    • beforeRouteEnter
    • beforeRouteUpdate (2.2 新增)
    • beforeRouteLeave
    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`
      }
    }
    

    ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容