VueRouter 基础回顾
要点一览
思维导图链接:https://www.processon.com/view/link/602f374e6376891d5f86f8d1
VueRouter 的基本使用
HTML
1. 创建路由组件的占位
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view>
2. 创建链接
<!-- 通过传入 `to` 属性指定链接 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
JS
1. 引入
import Vue from "vue"
import VueRouter from "vue-router"
2. 注册路由插件
Vue.use(VueRouter)
3. 定义路由规则
const routes = [
{
path:"/",
name:"index",
component: Index
}
]
4. 创建路由对象
const router = new VueRouter({
routes
})
5. 在Vue实例中注册 router 对象
new Vue({
router,
render: h => h(App)
}).$mount("#app")
注入路由器后,可以在任意组件内通过 this.$router
访问路由器,也可以通过 this.$route
访问当前路由。
$router
路由器,vueRouter 实例,通过在 Vue 根实例的 router 配置传入。
Props
属性 | 类型 | 说明 |
---|---|---|
app | Vue instance | 配置了 router 的 Vue 根实例 |
mode | string | 路由使用的模式 |
currentRoute | Route | 当前路由对应的路由信息对象(即 $route ) |
START_LOCATION | Route | 以路由对象的格式展示初始路由地址,即路由开始的地方。可用在导航守卫中以区分初始导航 |
Methods
方法 | 说明 | 备注 |
---|---|---|
beforeEach | ||
beforeResolve | ||
afterEach | ||
push | ||
replace | ||
go | ||
back | ||
forward | ||
getMatchedComponents | ||
resolve | ||
addRoutes | ||
addRoute | ||
addRoute | ||
getRoutes | ||
onReady | ||
onError |
$route
当前路由对象,表示当前激活的路由的状态信息。不可变 (immutable) ,每次成功的导航后都会产生一个新的对象。
Props
属性 | 类型 | 说明 |
---|---|---|
path | string | 对应当前路由的路径,总是解析为绝对路径,如 “/foo/bar ” |
params | Object | 一个 key/value 对象,包含了动态片段和全匹配片段。 如:模式/user/:username ,匹配路径/user/evan ,$route.params ={ username: 'evan' } |
query | Object | 一个 key/value 对象,表示 URL 查询参数。如,对于路径 /foo?user=1 ,则有 $route.query.user == 1 |
hash | string | 当前路由的 hash 值 (带 #) |
fullPath | string | 完成解析后的 URL,包含查询参数和 hash 的完整路径 |
matched | Array | 一个数组,包含当前路由的所有嵌套路径片段的路由记录 |
name | string | 当前路由的名称 |
redirectedFrom | string | 如果存在重定向,即为重定向来源的路由的名字 |
动态路由
使用
把某种模式匹配到的所有路由,全都映射到同个组件。例如,商品详情页,都使用 Detail 组件。
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{
path: '/detail/:id',
component: Detail
}
]
})
获取路径参数
- 直接通过
$route.params
获取。“路径参数”使用冒号:
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: ‘evan’ } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: ‘evan’, post_id: ‘123’ } |
- 通过 props 接收。需要在路由配置中设置
props:true
const router = new VueRouter({
routes: [
{
path: '/detail/:id',
component: Detail,
props: true //通过props把参数传递给组件
}
]
})
响应路由参数变化
注意!当使用路由参数时,例如从 /user/foo
导航到 /user/bar
,原来的组件实例会被复用。这意味着组件的生命周期钩子不会再被调用。
需要对路由参数的变化作出响应,可以通过以下两种方式:
1. watch (监测变化) $route 对象
const User = {
template: '...',
watch: {
$route(to, from) {
// 对路由变化作出响应...
}
}
}
2. 使用 beforeRouteUpdate 进行导航守卫
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// 对路由变化作出响应...
// 记得要调用 next()
}
}
路由嵌套
需要进行路由嵌套,在路由规则中使用 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
},
{
// 提供一个【空的】子路由,当 /user/:id 匹配成功,UserHome 会被渲染在 User 的 <router-view> 中
// 如果没有提供这个空的子路由,User 的出口不会渲染任何东西。
path: '',
component: UserHome
}
]
}
]
})
编程式导航
- router.push
- router.replace
- router.go
router.push(location, onComplete?, onAbort?)
参数可以是一个字符串路径,或者一个描述地址的对象
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由(可以使用 name 而不用 path)
router.push({ name: 'user'})
// 命名的路由,带参数
router.push({ name: 'user', params: { userId: '123' }}) // => /user/123
// 带查询参数
router.push({ path: 'register', query: { plan: 'private' }}) // => /register?plan=private
注意:如果提供了 path,params 会被忽略。
const userId = '123'
// name + params
router.push({ name: 'user', params: { userId }}) // -> /user/123
// 带有手写参数的 path
router.push({ path: `/user/${userId}` }) // -> /user/123
// 错误使用:这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
router.replace(location, onComplete?, onAbort?)
与 router.push
基本相同,唯一的不同就是,它不会向 history 添加新记录,而是替换当前记录。
router.go(n)
参数是一个整数,意思是在 history 记录中向前或者后退多少步。类似 window.history.go(n)
VueRouter 路由守卫
1)全局级别
前置守卫:beforeEach
解析守卫:beforeResolve
导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后调用
后置钩子:afterEach
不会接受 next 函数也不会改变导航本身。
2)路由级别
前置守卫:beforeEnter
在路由规则中给特定路由进行配置。
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
3)组件级别
beforeRouteEnter
组件实例还没被创建,无法获取组件实例 this
。但可以通过 next 中的回调获取组件实例(导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。仅 beforeRouteEnter 支持传递回调)
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
beforeRouteUpdate
当前路由改变,但该组件被复用时调用
beforeRouteLeave
导航离开该组件的对应路由时调用,此时仍可获取组件实例 this
4)参数解析
router.***((to, from, next) => { ...})
- to : Route ,即将要进入的目标 路由对象
- from : Router ,当前导航正要离开的路由
- next : Function ,要调用该方法来 resolve 这个钩子