编程式导航
在前一节的代码中,执行路由切换的操作都是以单击 <router-link> 组件来触发导航操作的,这种方式称作声明式导航。在 vue-router 中除了使用 <router-link> 来定义导航链接外,还可以借助 router
的实例方法通过编写代码来实现,这就是所谓的编程式导航。下面介绍编程式导航的几个常用方法。
router.push(location, onComplete?, onAbort?)
在之前的代码中曾使用过 this.$route.params
获取路由的参数,this.$route
为当前的路由对象,在实现路由切换时,如果使用编程式导航,需要使用 this.$router.push
方法,通过 this.$router
获取的是设置在根实例中的一个 Vue Router 的实例,push
方法是由实例对象提供的,所以不要把 this.$route
和 this.$router
搞混了。
router.push
方法的第一个参数可以是一个字符串路径,也可以是一个描述地址的对象,在这个对象中可以设置传递到下一个路由的参数。onComplete
和 onAbort
作为第二个和第三个参数分别接收一个回调函数,它们分别表示当导航成功时触发和导航失败时触发(导航到相同的路由或在当前导航完成之前就导航到另一个不同的路由),不过这两个参数不是必须要传入的,如示例代码7-8-1所示。
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 带查询参数,变成 /user?userId=test
router.push({ path: '/user', query: { userId: 'test' }})
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
在上面列出的方法中,在调用 router.push
方法时,第一个参数设置成对象,可以实现导航和传递参数的功能,path
对应路由配置信息中定义的 path
,query
设置传递的参数,在导航后的组件可以使用 this.$route.query
来接收,最后一种使用 name
的方式来表明跳转的路由,params
设置传递的参数,这里的方式为命名路由。
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由或者执行一些跳转时。在创建 router
实例时,在 routes
配置中给某个路由设置 name
属性,如示例代码7-8-2所示。
var router = new VueRouter({
routes: [
{
path: '/user/:id',
name: 'user',
component: User
}
]
})
那么使用 name+params
和 path+query
有什么区别呢?总结如下:
-
进行路由配置时,
path
是必配的,而name
可以选配。 -
使用
name
或者path
进行导航时,当传参可以使用params
时,接收参数使用$route.parmas
;当传参使用query
时,接收参数使用$route.query
。 -
query
的参数一般以?xx=xx
形式跟在路径后面。query
类似于Ajax
中的get
传参,params
则类似于post
,简单来说,前者在浏览器地址栏中显示参数,后者则不显示。
注意,当采用 name
进行导航时,如果 path
里面有需要的参数,例如 :id
,那么对应的 params
也需要传递 id
参数,否则将无法被正确导航,代码如下:
// 对应path:'/user/:id'
this.$router.push({
name:'user',
params:{
id:id // 必须传递id
}
})
调用 router.push
方法时,会向 history
栈添加一个新的记录,所以,当用户单击浏览器后退按钮时,就会回到之前的 URL。如果这时采用 query
传参,那么页面刷新时参数可以保留,效果如图7-3所示。

router.replace(location, onComplete?, onAbort?)
router.replace
方法也可以进行路由切换从而实现导航,与 router.push
很像,唯一不同的是,它不会向 history
添加新记录,而是跟它的方法名一样,替换 (replace
) 掉当前的 history
记录。也就是当用户单击浏览器返回时,并不会向 history
添加记录。
router.go(Number)
router.go
方法的参数是一个整数,意思是在 history
记录中向前或者后退多少步,类似于 window.history.go(n)
,如示例代码7-8-3所示。
// 在浏览器记录中前进一步,等同于 router.forward()
router.go(1)
// 后退一步记录,等同于 router.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,就会失败
router.go(-100)
router.go(100)
router.reslove(location)
router.reslove
方法可以将一个 router
的 location
配置转换成一个标准对象,提供 base
和 href
属性,例如,如果不想采用 router
调整,可以使用浏览器原生的跳转,如示例代码7-8-4所示。
let routeData = router.resolve({
path: path,
query: query || {}
})
window.open(routeData.href);
这样就可以将页面链接的根路径解析出来,而不用写死在代码中,但是如果 path
并不是在 router
中定义的,那么 resolve
方法将会报错。