动态路由匹配
{path: '/user/:id', component: User}
this.$route.params
响应路由参数的变化
路由跳转时,原来的组件实例会被复用,这意味着组件的生命周期钩子并不会再被调用
复用组件时,想对路由参数的变化做出响应的话,可以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()
}
}
嵌套路由
使用children
const router = new VueRouter({
routes: [{
path: '/user/:id',
component: User,
children: [
{path: '', component: UserHome}
]
}]
})
编程式的导航
router.push(location, onComplete?, onAbort?)
2.2.0+提供了onComplete/onAbort回调函数,在导航成功完成或终止后调用
注意:在 Vue 实例内部,你可以通过 router.push。
这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL
#声明式
#编程式
router.push(...)
router.push('home') //字符串
router.push({path:'home'}) // 对象
router.push({name: 'user',params: {userId: 123}})
router.push({path: 'register', query: {plan: 'private'}})
router.push({path: `/user/${userId}` }) // /user/123
router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
#声明式
#编程式
router.replace(...)
router.go(n)
类似 window.history.go(n)
命名路由
name
命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,这个时候命名视图就派上用场了
// 没有设置名字,默认为default
const router = new VueRouter({
routes: [
{
path; '/',
components:{
default:Foo,
b:Baz
}
}
]
})
重定向和别名
const router = new VueRouter({
routes: [
{
path: '/a', redirect: '/b'
},
{path: '/a', redirect: {name: 'foo'}},
{path: '/a',redirect: to=> {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
注意: 导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上
别名
routes: [
// 访问 /b,url会保持/b,但是匹配路由为/a,
{path: '/a', component: A, alias: '/b'}
]
路由组件传参
在组件中使用$route会使之与对应路由形成高度耦合,从而使组件只能在某些特定的URL上使用,使用props组件和路由解藕
const User = {
template: 'User {{ $route.params.id }}'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
通过props解藕
const User = {
props: ['id'],
template: 'User{{ id }}'
}
const router = new VueRouter({
routes: [
{path: 'user/id', component: User, props: true}, // props设置为true,route.params 将会被设置为组件属性
// 命名视图的路由
{ path: '/user/:id',
components: {default: User, siderbar: sidebar},
porps: {default: true, sidebar: false}
}
]
})
HTML5 History 模式
vue-router默认hash模式,使用URL的hash来模拟一个完整的URL,当URL改变,页面不会重新加载(配合onhashchange事件)
history模式,利用history.pushState API来完成URL跳转而无须重新加载页面
new VueRouter({
mode: 'history',
routes: [...]
})
history模式,需要后台配置支持
导航守卫
参数或查询的改变并不会触发进入/离开的导航守卫,组件会复用,可以通过watch $route对象或使用 beforeRouteUpdate 的组件内守卫
全局守卫
router.beforeEach 全局前置守卫
const router = new VueRouter({...})
router.beforeEach((to, from ,next)=>{
//...
})
- to: Route: 即将要进入的目标路由对象
- from: Route: 当前导航正要离开的路由
- next:Function 一定要调用该方法来resolve这个钩子,执行效果依赖 next 方法的调用参数
next():进行管道中的下一个钩子,如果全部钩子执行完了,则导航的状态就是confirmed(确认的)
next(false):中断当前 的导航,如果浏览器的URL改变了(可能是用户手动 或浏览器后退),那么URL地址会重置到from路由对应的地址
next('/')或者next({path: '/'}):跳转到一个不同的地址,当前的导航被中断,然后 进行一个新的导航
next(error) 2.4.0+ 如果传入 的是一个error实例,则导航会被中止且该错误会被传递给router.onError()注册过的回调
#全局解析守卫
2.5.0新增
router.beforeResolve
#全局后置钩子
router.afterEach((to,from)=>{
// 没有next
})
路由独享的守卫
写在路由中
const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next){
...
}
}]
})
组件内的守卫
- beforeRouteEnter 不!能!获取组件实例
this
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
- beforeRouteUpdate 2.2新增 // 在当前路由改变,但是该组件被复用时调用
- beforeRouteLeave
#完整的导航解析流程
导航被触发——组件中调用 beforeRouteLeave——全局beforeEach——在重用的组件里调用beforeRouteUpdate——路由配置的beforeEnter——解析异步路由组件——被激活的组件调用beforeRouteEnter——全局的beforeResolve——导航被确认——调用全局的afterEach——触发DOM更新——调用beforeRouteEnter中给next的回调函数
路由元信息
meta
一个路由匹配到的所有路由记录会暴露为 route.matched 数组
// 在全局导航守卫中检查元字段
router.beforeEach((to, from,next)=>{
if(to.matched.some(record => record.meta.requiresAuth)){
next()
}
})
过渡动效
``
watch: {
'$route' (to, from){
...
}
}
###数据获取
- 导航完成之后获取
在created钩子函数中获取
- 导航完成之前获取
在组件 beforeRouteEnter中获取数据,获取成功调用 next()方法
###滚动行为
注意: 这个功能只在支持 history.pushState 的浏览器中可用。
const router = new VueRouter({
routes: [],
scrollBehavior(to, from , savedPositon){
// return 期望滚动到哪个位置
//{ x: number, y: number }
}
})
第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
###路由懒加载
const Foo = ()=>import('./Foo.vue')