路由vue-router基礎
官方文檔
1. 基本例子
html
<script src="https://unpkg.com/vue/dist/vue.js"></script> <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>
js
// 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') // 現在,應用已經啟動了!
2. 動態路由匹配
定義routes時候
routes: [ // 動態路徑參數 以冒號開頭 { path: '/user/:id', component: User } ]
獲取參數方法
this.$route.params
可以設置多個參數
```
//格式:
/user/:username/post/:post_id
//使用
/user/evan/post/123
//this.$route.params結果:
{ username: ‘evan‘, post_id: 123 }
4. 路由參數變化 提醒一下,當使用路由參數時,例如從 /user/foo 導航到 user/bar,原來的組件實例會被復用。因為兩個路由都渲染同個組件,比起銷毀再創建,復用則顯得更加高效。不過,這也意味著組件的生命周期鉤子不會再被調用。 復用組件時,想對路由參數的變化作出響應的話,你可以簡單地 watch(監測變化) $route 對象:
const User = {
template: ‘...‘,
watch: {
‘$route‘ (to, from) {
// 對路由變化作出響應...
}
}
}
或者使用 2.2 中引入的 beforeRouteUpdate 守衛:
const User = {
template: ‘...‘,
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don‘t forget to call next()
}
}
5. 匹配優先級
有時候,同一個路徑可以匹配多個路由,此時,匹配的優先級就按照路由的定義順序:誰先定義的,誰的優先級就最高。
6. 高級匹配模式
vue-router 使用 path-to-regexp 作為路徑匹配引擎,所以支持很多高級的匹配模式,[文檔](https://github.com/pillarjs/path-to-regexp#parameters)
# 3. 嵌套路由
1. 頂層出口例子
const User = {
template: ‘User {{ $route.params.id }}‘
}
const router = new VueRouter({
routes: [
{ path: ‘/user/:id‘, component: User }
]
})
2. 嵌套出口例子
const User = {
template: <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div>
}
const router = new VueRouter({
routes: [
{ path: ‘/user/:id‘, component: User,
children: [
{
// 當 /user/:id/profile 匹配成功,
// UserProfile 會被渲染在 User 的
path: ‘profile‘,
component: UserProfile
},
{
// 當 /user/:id/posts 匹配成功
// UserPosts 會被渲染在 User 的
path: ‘posts‘,
component: UserPosts
}
]
}
]
})
3. 空的子路由
當你訪問 /user/foo 時,User 的出口是不會渲染任何東西,這是因為沒有匹配到合適的子路由。如果你想要渲染點什麽,可以提供一個 空的 子路由:
const router = new VueRouter({
routes: [
{
path: ‘/user/:id‘, component: User,
children: [
// 當 /user/:id 匹配成功,
// UserHome 會被渲染在 User 的
{ path: ‘‘, component: UserHome },
// ...其他子路由
]
}
]
})
# 4. 編程式導航
實現跳轉兩種方式
- 使用<router-link>
- 編寫代碼(route.push(),route.replace(),router.go())
完整模式
router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)
1. router.push
router.push 方法向 history 棧添加一個新的記錄,所以,當用戶點擊瀏覽器後退按鈕時,則回到之前的 URL。
/ 字符串
router.push(‘home‘)
// 對象
router.push({ path: ‘home‘ })
// 命名的路由
router.push({ name: ‘user‘, params: { userId: 123 }})
// 帶查詢參數,變成 /register?plan=private
router.push({ path: ‘register‘, query: { plan: ‘private‘ }})
**註意:如果提供了 path,params 會被忽略,上述例子中的 query 並不屬於這種情況。取而代之的是下面例子的做法,你需要提供路由的 name 或手寫完整的帶有參數的 path:**
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
**同樣的規則也適用於 router-link 組件的 to 屬性。**
2. router.replace
router.replace跟 router.push 很像,唯一的不同就是,它不會向 history 添加新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。
3. router.go
router.go(n)這個方法的參數是一個整數,意思是在 history 記錄中向前或者後退多少步,類似 window.history.go(n)。
// 在瀏覽器記錄中前進一步,等同於 history.forward()
router.go(1)
// 後退一步記錄,等同於 history.back()
router.go(-1)
// 前進 3 步記錄
router.go(3)
// 如果 history 記錄不夠用,那就默默地失敗唄
router.go(-100)
router.go(100)
4. 參數
在 2.2.0+,可選的在 router.push 或 router.replace 中提供 onComplete 和 onAbort 回調作為第二個和第三個參數。這些回調將會在導航成功完成 (在所有的異步鉤子被解析之後) 或終止 (導航到相同的路由、或在當前導航完成之前導航到另一個不同的路由) 的時候進行相應的調用。
註意:如果目的地和當前路由相同,只有參數發生了改變 (比如從一個用戶資料到另一個 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 來響應這個變化 (比如抓取用戶信息)
# 5. 命名路由
有時候,通過一個名稱來標識一個路由顯得更方便一些,特別是在鏈接一個路由,或者是執行一些跳轉的時候。你可以在創建 Router 實例的時候,在 routes 配置中給某個路由設置名稱。
const router = new VueRouter({
routes: [
{
path: ‘/user/:userId‘,
name: ‘user‘,
component: User
}
]
})
# 6. 命名視圖
有時候想同時(同級)展示多個視圖,而不是嵌套展示,例如創建一個布局,有 sidebar(側導航) 和 main(主內容) 兩個視圖,這個時候命名視圖就派上用場了。你可以在界面中擁有多個單獨命名的視圖,而不是只有一個單獨的出口。如果 router-view 沒有設置名字,那麽默認為 default。
一個視圖使用一個組件渲染,因此對於同個路由,多個視圖就需要多個組件。確保正確使用 components 配置(帶上 s):
const router = new VueRouter({
routes: [
{
path: ‘/‘,
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
# 7. 重定向和別名
1. 重定向
重定向也是通過 routes 配置來完成,下面例子是從 /a 重定向到 /b:
const router = new VueRouter({
routes: [
{ path: ‘/a‘, redirect: ‘/b‘ }
]
})
重定向的目標也可以是一個命名的路由:
const router = new VueRouter({
routes: [
{ path: ‘/a‘, redirect: { name: ‘foo‘ }}
]
})
甚至是一個方法,動態返回重定向目標:
const router = new VueRouter({
routes: [
{ path: ‘/a‘, redirect: to => {
// 方法接收 目標路由 作為參數
// return 重定向的 字符串路徑/路徑對象
}}
]
})
更多實例
routes: [
{ path: ‘/‘, component: Home,
children: [
{ path: ‘‘, component: Default },
{ path: ‘foo‘, component: Foo },
{ path: ‘bar‘, component: Bar },
{ path: ‘baz‘, name: ‘baz‘, component: Baz },
{ path: ‘with-params/:id‘, component: WithParams },
// relative redirect to a sibling route
{ path: ‘relative-redirect‘, redirect: ‘foo‘ }
]
},
// absolute redirect
{ path: '/absolute-redirect', redirect: '/bar' },
// dynamic redirect, note that the target route `to` is available for the redirect function
{ path: '/dynamic-redirect/:id?',
redirect: to => {
const { hash, params, query } = to
if (query.to === 'foo') {
return { path: '/foo', query: null }
}
if (hash === '#baz') {
return { name: 'baz', hash: '' }
}
if (params.id) {
return '/with-params/:id'
} else {
return '/bar'
}
}
},
// named redirect
{ path: '/named-redirect', redirect: { name: 'baz' }},
// redirect with params
{ path: '/redirect-with-params/:id', redirect: '/with-params/:id' },
// catch all redirect
{ path: '*', redirect: '/' }
]
```
- 別名
『重定向』的意思是,當用戶訪問 /a時,URL 將會被替換成 /b,然後匹配路由為 /b。
別名: /a 的別名是 /b,意味著,當用戶訪問 /b 時,URL 會保持為 /b,但是路由匹配則為 /a,就像用戶訪問 /a 一樣。
上面對應的路由配置為:
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
更多例子
routes: [
{ path: '/home', component: Home,
children: [
// absolute alias
{ path: 'foo', component: Foo, alias: '/foo' },
// relative alias (alias to /home/bar-alias)
{ path: 'bar', component: Bar, alias: 'bar-alias' },
// multiple aliases
{ path: 'baz', component: Baz, alias: ['/baz', 'baz-alias'] }
]
}
]
8. 向路由組件傳遞props
實例:
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true }
// 對於包含命名視圖的路由,你必須分別為每個命名視圖添加props選項:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
- 布爾模式
如果props被設置為true,route.params將會被設置為組件屬性。
- 對象模式
如果props是一個對象,它會被按原樣設置為組件屬性。當props是靜態的時候有用。
const router = new VueRouter({
routes: [
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
]
})
- 函數模式
你可以創建一個函數返回props。這樣你便可以將參數轉換成另一種類型,將靜態值與基於路由的值結合等等。
const router = new VueRouter({
routes: [
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})
Url: /search?q=vue 會將 {query: "vue"} 作為屬性傳遞給SearchUser組件。
9. HTML5 History模式
vue-router 默認 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新加載。
如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新加載頁面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
當你使用 history 模式時,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!
不過這種模式要玩好,還需要後臺配置支持。因為我們的應用是個單頁客戶端應用,如果後臺沒有正確的配置,當用戶在瀏覽器直接訪問 http://oursite.com/user/id 就會返回 404,這就不好看了。
所以呢,你要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。
給個警告,因為這麽做以後,你的服務器就不再返回 404 錯誤頁面,因為對於所有路徑都會返回 index.html 文件。為了避免這種情況,你應該在 Vue 應用裏面覆蓋所有的路由情況,然後在給出一個 404 頁面。
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFoundComponent }
]
})
路由vue-router基礎