路由實(shí)現(xiàn)的方式
聲明式。<router-link :to="...">
編程式。router.push(...)? 、router.replace(...)
<router-link> 屬于內(nèi)部調(diào)用,等同于router.push()。
router.replace?跟?router.push?很像,唯一的不同就是,它不會(huì)向 history 添加新記錄,而是跟它的方法名一樣 —— 替換掉當(dāng)前的 history 記錄。
router.push('home')? ?// 字符串?
router.push({ path: 'home' })? ?// 對(duì)象
router.push({ name: 'user', params: { userId: 123 }})? ?// 命名的路由?
router.push({ path: 'register', query: { plan: 'private' }})? ?// 帶查詢參數(shù),變成 /register?plan=private?
注意:如果提供了?path,params?會(huì)被忽略,上述例子中的?query?并不屬于這種情況。取而代之的是下面例子的做法,你需要提供路由的?name?或手寫(xiě)完整的帶有參數(shù)的?path:
const userId = 123
router.push({ name: 'user', params: { userId }})? ? ? ? // -> /user/123
router.push({ path: `/user/${userId}` })? ? ? ? ?// -> /user/123?
router.push({ path: '/user', params: { userId }})? ? ? ? ?// -> /user
同樣的規(guī)則也適用于?router-link?組件的?to?屬性。
router.go(n)
參數(shù)是一個(gè)整數(shù),意思是在 history 記錄中向前或者后退多少步,類(lèi)似?window.history.go(n)。
router.go(1)
router-link 渲染成 a 標(biāo)簽,router-view 渲染成路由切換區(qū)域。
<div>
? ? <router-link class='router-link-active' to='/home'>go to home</router-link>
? ? <router-link to='/power'>go to home</router-link>
</div>
<router-view></router-view>
將組件(components)映射到路由(routes)。
import Vue from 'vue'
import VueRouter from ’vue-router‘
import Home from './component/home'
import Power from './component/power'
Vue.use(VueRouter)
const routes = [
? ? { path: '/home', component: Home},
? ? { path: '/power/:id', component: Power}??
]
export default new VueRouter({ routes })
動(dòng)態(tài)路由配置
????路徑參數(shù),使用 :id 將不同Id的用戶映射到相同的路由,如(/user/foo?和?/user/bar)
????模板參數(shù),
const User = {
? template: '<div>User {{ $route.params.id }}</div>'
}
通過(guò)注入路由器,我們可以在任何組件內(nèi)通過(guò)?this.$router?訪問(wèn)路由器和當(dāng)前路由。
this.$route.params
this.$route.go(-1)
this.$route.push('/')
響應(yīng)路由參數(shù)的變化
動(dòng)態(tài)路由切換時(shí),原來(lái)的組件實(shí)例會(huì)被調(diào)用,每個(gè)路由渲染的是同個(gè)組件,復(fù)用高效,但同時(shí)組件的生命周期鉤子將不會(huì)再被調(diào)用。
故,服用組件時(shí),使用 watch 監(jiān)控 $route 對(duì)象,實(shí)現(xiàn)組件相應(yīng)的改變。
const User = {
????template: '...',
????watch: {
????????'$route' (to, from) { // 對(duì)路由變化作出響應(yīng)... }
????}
}
或使用2.2中的 beforeRouteUpdate 守衛(wèi)
const User = {
????template: '...',
????beforeRouteUpdate (to, from, next) {
????????// react to route changes...
????????// don't forget to call next()
????}
}
嵌套路由
1、在html中再次添加 router-link 、router-view
2、js中在routes中的路由中添加 children 屬性。
3、在children中添加對(duì)象屬性值,屬性與一級(jí)路由一樣。
4、當(dāng)訪問(wèn)該 User 路由時(shí),不會(huì)渲染子路由,除非子路由中有 path:' ' 。
routes: [{
????path: '/user/:id', component: User,
????children: [ {
????????path: 'profile', component: UserProfile
????}
}]
命名路由
在創(chuàng)建 Router 實(shí)例的時(shí)候,在?routes?配置中給某個(gè)路由設(shè)置名稱 name 。
routes: [ { path: '/user/:userId', name: 'user', component: User } ]
要鏈接到一個(gè)命名路由,可以給?router-link?的?to?屬性傳一個(gè)對(duì)象
<router-link :to="{ name: 'user', params: { id: 123 }}">User</router-link>
router.push() 也是傳一個(gè)對(duì)象
router.push({ name: 'user', params: { userId: 123 }})
命名視圖(多個(gè)路由層)
在界面中擁有多個(gè)單獨(dú)命名的視圖,而不是只有一個(gè)單獨(dú)的出口。
如果?router-view?沒(méi)有設(shè)置名字(name),那么默認(rèn)為?default。
<router-view></router-view>?
?<router-view name="a"></router-view>
一個(gè)視圖使用一個(gè)組件渲染,因此對(duì)于同個(gè)路由,多個(gè)視圖就需要多個(gè)組件。確保正確使用?components?配置(帶上 s):
routes: [ {
????path: '/',
????components: {
????????default: Foo,
????????a: Bar
????}
} ]
嵌套命名視圖
使用命名視圖創(chuàng)建嵌套視圖的復(fù)雜布局。
<router-view/>
<router-view name="helper">
{
????path: '/settings',?
????component: UserSettings,
????children: [{
????????path: 'emails',
????????component: UserEmailsSubscriptions
????}, {
????????path: 'profile',
????????components: {
????????????default: UserProfile,
????????????helper: UserProfilePreview
????????}
????}]
}
重定向和別名
重定向 redirect
routes: [
????{ path: '/a', redirect: '/b' },? //?從?/a?重定向到?/b
? ??{ path: '/a', redirect: { name: 'foo' }},? //?重定向的目標(biāo)也可以是一個(gè)命名的路由:
????{ path: '/a', redirect: to => {?? ? //??甚至是一個(gè)方法,動(dòng)態(tài)返回重定向目標(biāo):
????????// 方法接收 目標(biāo)路由 作為參數(shù)
????????// return 重定向的 字符串路徑/路徑對(duì)象
????}}
]
別名?alias
“重定向” 的意思是,當(dāng)用戶訪問(wèn)?/a時(shí),URL 將會(huì)被替換成?/b 路由。
“別名” 是?/a?的別名(第二個(gè)名字)是?/b。當(dāng)用戶訪問(wèn)?/b?時(shí),URL 會(huì)保持為?/b,但是路由匹配則為?/a,就像用戶訪問(wèn)?/a?一樣。
{ path: '/a', component: A, alias: '/b' }
路由組件傳參
在組件中使用?$route?會(huì)使之與其對(duì)應(yīng)路由形成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。
使用?props?將組件和路由解耦:
const User = {
????props: ['id'],
????template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
????routes: [
????????{ path: '/user/:id', component: User, props: true },?
????????{
????????????path: '/user/:id',
????????????components: { default: User, sidebar: Sidebar },
????????????props: { default: true, sidebar: false }
????????}
????]
})
如果?props?被設(shè)置為?true,route.params?將會(huì)被設(shè)置為組件屬性。
對(duì)象模式
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
函數(shù)模式
創(chuàng)建一個(gè)函數(shù)返回?props。這樣你便可以將參數(shù)轉(zhuǎn)換成另一種類(lèi)型,將靜態(tài)值與基于路由的值結(jié)合等等。
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
HTML5 History 模式
vue-router?默認(rèn) hash 模式 —— 使用 URL 的 hash 來(lái)模擬一個(gè)完整的 URL,于是當(dāng) URL 改變時(shí),頁(yè)面不會(huì)重新加載。
如果不想要很丑的 hash,我們可以用路由的?history 模式,這種模式充分利用?history.pushState?API 來(lái)完成 URL 跳轉(zhuǎn)而無(wú)須重新加載頁(yè)面。
const router = new VueRouter({
????mode: 'history',
????routes: [...]
})
當(dāng)你使用 history 模式時(shí),URL 就像正常的 url,例如?http://yoursite.com/user/id
不過(guò)這種模式要玩好,還需要后臺(tái)配置支持。因?yàn)槲覀兊膽?yīng)用是個(gè)單頁(yè)客戶端應(yīng)用,如果后臺(tái)沒(méi)有正確的配置,當(dāng)用戶在瀏覽器直接訪問(wèn)?http://oursite.com/user/id?就會(huì)返回 404,這就不好看了。
所以呢,你要在服務(wù)端增加一個(gè)覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態(tài)資源,則應(yīng)該返回同一個(gè)?index.html?頁(yè)面,這個(gè)頁(yè)面就是你 app 依賴的頁(yè)面。