Vue-Router簡介
Vue-Router是Vue.js官方維護的路由插件,同時也是官方推薦的路由插件近迁。它與Vue.js內(nèi)核深度結合代嗤,讓開發(fā)單頁應用更加容易簡便。
基本配置
- **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 }
]
//創(chuàng)建router實例
const router = new VueRouter({
routes // (縮寫)相當于 routes: routes
})
//掛載實例
const app = new Vue({
router
}).$mount('#app')
動態(tài)路由配置
-
場景:通過URL傳遞參數(shù)
const router = new VueRouter({ routes: [ // 動態(tài)路徑參數(shù) 以冒號開頭 { path: '/user/:id', component: User } ] })
動態(tài)路徑參數(shù)使用冒號
:
標記拆火,對應的值都會設置到$route.params
中。此處可通過this.$route.params.id
來獲取id涂圆,在模板中可以省略this.
们镜,如const User = { template: '<div>User {{ $route.params.id }}</div>' }
如果是非必須的參數(shù),可在參數(shù)后加一個
?
润歉,如path:''/page1/:id?'
對于帶查詢參數(shù)的URL模狭,如/page1?id=123
可用$route.query
訪問,如果沒有查詢參數(shù)踩衩,則是個空對象嚼鹉。
響應路由參數(shù)的變化
當使用路由參數(shù)時,例如從 /page1/123
導航到 /page1/321
驱富,原來的組件實例會被復用反砌。因為兩個路由都渲染同個組件,比起銷毀再創(chuàng)建萌朱,復用則顯得更加高效宴树。不過,這也意味著組件的生命周期鉤子不會再被調(diào)用晶疼。
復用組件時酒贬,想對路由參數(shù)的變化作出響應的話,你可以簡單地watch
(監(jiān)測變化) $route
對象翠霍。
watch: {
'$route' (to, from) {
// 對路由變化作出響應...
}
}
或者使用 2.2 中引入的 beforeRouteUpdate
守衛(wèi):
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
嵌套路由
實際生活中的應用界面锭吨,通常由多層嵌套的組件組合而成。同樣地寒匙,URL 中各段動態(tài)路徑也按某種結構對應嵌套的各層組件零如。借助 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>
創(chuàng)建a
標簽來定義導航鏈接,我們還可以借助router
的實例方法肖卧,通過編寫代碼來實現(xiàn)蚯窥。
// 字符串
router.push('home')
// 對象
router.push({ path: 'home' })
// 命名的路由-> /user/123
router.push({ name: 'user', params: { userId: 123 }})
// 帶查詢參數(shù),變成 /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
命名路由
有時候拦赠,通過一個名稱來標識一個路由顯得更方便一些,特別是在鏈接一個路由葵姥,或者是執(zhí)行一些跳轉的時候荷鼠。命名路由可以通過$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
提供的導航守衛(wèi)主要用來通過跳轉或取消的方式守衛(wèi)導航。有多種機會植入路由導航過程中:全局的, 單個路由獨享的, 或者組件級的敞临。
記住參數(shù)或查詢的改變并不會觸發(fā)進入/離開的導航守衛(wèi)态辛。你可以通過觀察 $route
對象來應對這些變化,或使用 beforeRouteUpdate
的組件內(nèi)守衛(wèi)挺尿。
-
全局守衛(wèi)
你可以使用
router.beforeEach
注冊一個全局前置守衛(wèi):const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
當一個導航觸發(fā)時奏黑,全局前置守衛(wèi)按照創(chuàng)建順序調(diào)用。守衛(wèi)是異步解析執(zhí)行编矾,此時導航在所有守衛(wèi) resolve 完之前一直處于 等待中熟史。
每個守衛(wèi)方法接收三個參數(shù):
- to: Route: 即將要進入的目標 路由對象
- from: Route: 當前導航正要離開的路由
-
next: Function: 一定要調(diào)用該方法來 resolve 這個鉤子。執(zhí)行效果依賴
next
方法的調(diào)用參數(shù)窄俏。- next(): 進行管道中的下一個鉤子蹂匹。如果全部鉤子執(zhí)行完了,則導航的狀態(tài)就是 confirmed (確認的)凹蜈。
-
next(false): 中斷當前的導航限寞。如果瀏覽器的 URL 改變了(可能是用戶手動或者瀏覽器后退按鈕),那么 URL 地址會重置到
from
路由對應的地址仰坦。 - next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址履植。當前的導航被中斷,然后進行一個新的導航悄晃。
-
next(error): (2.4.0+) 如果傳入
next
的參數(shù)是一個Error
實例玫霎,則導航會被終止且該錯誤會被傳遞給router.onError()
注冊過的回調(diào)。
確保要調(diào)用 next 方法,否則鉤子就不會被 resolved庶近。
-
全局解析守衛(wèi)
在 2.5.0+ 你可以用
router.beforeResolve
注冊一個全局守衛(wèi)翁脆。這和router.beforeEach
類似,區(qū)別是在導航被確認之前拦盹,同時在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后鹃祖,解析守衛(wèi)就被調(diào)用。 -
全局后置鉤子
你也可以注冊全局后置鉤子普舆,然而和守衛(wèi)不同的是恬口,這些鉤子不會接受
next
函數(shù)也不會改變導航本身:router.afterEach((to, from) => { // ... })
-
路由獨享的守衛(wèi)
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
-
組件內(nèi)的守衛(wèi)
最后,你可以在路由組件內(nèi)直接定義以下路由導航守衛(wèi):
beforeRouteEnter
-
beforeRouteUpdate
(2.2 新增) beforeRouteLeave
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調(diào)用 // 不沼侣!能祖能!獲取組件實例 `this` // 因為當守衛(wèi)執(zhí)行前,組件實例還沒被創(chuàng)建 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變蛾洛,但是該組件被復用時調(diào)用 // 舉例來說养铸,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候轧膘, // 由于會渲染同樣的 Foo 組件钞螟,因此組件實例會被復用。而這個鉤子就會在這個情況下被調(diào)用谎碍。 // 可以訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調(diào)用 // 可以訪問組件實例 `this` } }
?