官方文檔地址:https://router.vuejs.org/zh/
vue-router 是 Vue.js 官方的路由管理器。它和Vue.js深度集成,讓構建單頁面應用變得易如反掌。
1,這是一個簡單的栗子
HTML:
<script src="http://unpkg.com/vue/dist/vue.js"></script>
<script src="http://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>
JavaScript:
// 如果使用模塊化機制編程,導入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')
通過注入路由器,可以在任何組件內通過 this.$router
訪問路由器,也可以使用 this.$route
訪問當前路由。
2,動態路由匹配
當需要把某種模式匹配到的所有路由,全部映射到同一個組件上。例如,我們有一個User組件,對於ID各不相同的用戶,都要使用這個組件來渲染,在路由路徑中使用動態路由參數
實現該效果
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// 動態路由參數,以冒號開頭
{ path: '/user/:id', component: User }
]
})
這時,像 /user/id1
、/user/id2
都會映射到同一組件
使用 this.$route.params.id
獲取 參數的值
注
:當路由參數發生變化時,例如從/user/id1
跳轉到/user/id2
,原來的組件實例會被複用
,因爲兩個路由都渲染同個組件,比起銷燬再創建,複用會顯得更加高效。不過,這也意味着組件的生命週期鉤子不會再被調用
。
解決方案
:
1,使用 watch (監聽變化)$route
對象
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 對路由變化做出相應
}
}
}
2,使用 2.2 中引入的 beforeRouteUpdate
守衛
const User = {
template: '...',
beforeRouteUpdate(to, from, next) {
// react to route change ...
// don't forget to call next()
}
}
3,嵌套路由
父組件中需要 <router-view>
組件
父組件的路由對象中,需要有【children】屬性,當子組件的path爲空時,代表父組件匹配成功時, <router-view>
中需要渲染的組件。
先來個栗子
User組件
const User = {
template: `
<div id="user">
<h2>{{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`
}
路由
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
// 當/user/:id 匹配成功,
// userHome 會被渲染在 User的 <router-view>中
{ path: '', component: UserHome },
{
// 當 /user/:id/profile渲染成功,
// UserProfile 會被渲染再User的<router-view>中
path: 'profile',
component: 'UserProfile'
},
{
// 當 /user/:id/posts渲染成功,
// UserPosts 會被渲染再User的<router-view>中
path: 'posts',
component: 'UserPosts'
}
]
}
]
})
4,編程式導航
(1)router.push
會向 history棧中添加一個新紀錄,當用戶點擊瀏覽器後退按鈕時,會回到之前的URL,類似於 window.history.pushState
- 聲明式:
<router-link :to=""></router-link>
- 編程式:router.push(…)
栗子:
const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 當 path 和 params同時存在時 params不生效
router.push({ path: '/user', params: { userId }}) // -> /user
(2)router.replace
不會向 history 棧中添加新記錄,會替換掉當前的history 記錄(用法同上),類似於window.history.replaceState
- 聲明式:
<router-link :to='...' replace>
- 編程式:router.replace(…)
(3)router.go(n)
表示在history記錄中,向前或者向後退多少步,類似window.history.go(n)
栗子
// 在瀏覽器中前進一步,等同於 history.forward()
router.go(1)
// 後退一步記錄,等同於 history.back()
router.go(-1)
// 如果 history 記錄不夠用,那就默默地失敗唄
router.go(100)
router.go(-100)
5,命名路由
來個栗子
const router = new VueRouter({
routes: [
path: '/user/:userId',
name: 'user', // 對路由進行命名
component: User
]
})
聲明式路由跳轉寫法
<router-link :to="{ name: 'user', params: { userId: 123 } }"></router-link>
編程式路由跳轉寫法
router.push({ name: 'user', params: { userId: 123 } })
6,命名視圖
當需要創建一個佈局,有 sidebar(側導航)和main(主內容)兩個試圖時,就可以使用命名試圖
<router-view class='view one'></router-view>
<router-view class='view two' name='a'></router-view>
<router-view class='view three' name='b'></router-view>
使用 【components】(注意,這裏多個s)配置【router-view】的name值和需要顯示的組件綁定,如果沒有name屬性,默認使用【default】
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})