通过在 Vue 根实例的 router 配置传入 router 实例,$router、 $route 两个属性会被注入到每个子组件。

1️⃣ $router

$router 是路由实例对象。
除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

2️⃣ $router.push

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history(历史记录) 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 $router.push(…)。

  1. 1. 声明式:`<router-link :to="...">`
  2. 2. 编程式:`this.$router.push(...)`

image.png

  1. // 编程式导航传递参数:
  2. // 第一种:
  3. this.$router.push("/home/" + this.keyword + "?name=" + this.name)
  4. // 第二种:
  5. this.$router.push(`/home/${this.keyword}?name=${this.name}`)
  6. // 第三种:
  7. this.$router.push({ name:"home", params:{ keyword:this.keyword }, query:{ name:this.name } })

2️⃣ $router.replace

跟 router.push 很像,唯一的不同就是,它不会向 history (历史记录)添加新记录,而是替换掉当前的 history 记录。

  1. 1. 声明式:`<router-link :to="..." replace>`
  2. 2. 编程式:`this.$router.replace(...)`

2️⃣ $router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

  1. // 在浏览器记录中前进一步,等同于 history.forward()
  2. this.$router.go(1)
  3. // 后退一步记录,等同于 history.back()
  4. this.$router.go(-1)
  5. // 前进 3 步记录
  6. this.$router.go(3)
  7. // 如果 history 记录不够用,那就默默地失败
  8. this.$router.go(-100)
  9. this.$router.go(100)
  10. // 如果为 0 则会刷新页面
  11. this.$router.go(0)

1️⃣ $route

只读,路由信息对象。

2️⃣ $route.path

字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"

2️⃣ $route.params

一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。

2️⃣ $route.query

一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则返回一个对象 {user:’1’}

2️⃣ $route.hash

获取路由的 hash 值 (#后的内容) ,如果没有 hash 值,则为空字符串。

2️⃣ $route.fullPath

完成解析后的 URL,包含查询参数和 hash 的完整路径。

2️⃣ $route.matched

一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。

  1. const router = new VueRouter({
  2. routes: [ // 下面的对象就是路由记录
  3. {
  4. path: '/foo',
  5. component: Foo,
  6. children: [ // 这也是个路由记录
  7. {
  8. path: 'bar',
  9. component: Bar
  10. }
  11. ]
  12. }
  13. ]
  14. })
  15. // 当 URL 为 /foo/bar,\$route.matched 将会是一个包含从上到下的所有对象 (副本)。

2️⃣ $route.name

当前路由的名称,如果有的话

2️⃣ $route.redirectedFrom

如果存在重定向,即为重定向来源的路由的名字。

2️⃣ 示例

image.png
image.png

1️⃣ 使用问题

2️⃣ 多次触发报错

编程式路由导航多次触发相同的路由( 参数不变 ),会抛出警告出错。
路由跳转有两种形式,声明式和编程式。
声明式导航没有这类问题,因为 vue-router 底层已经处理过了。
因为编程式导航在新版本引入了 Promise ,而 Promise 需要成功和失败的回调,所以在正常使用时没有这两种回调就会报错。
解决方法:

  1. // 1. 在使用时写入成功和失败的回调函数 ( 这种写法只能解决单个,治标不治本 )
  2. this.$router.push(
  3. { name: "search", params: { key: this.search } },
  4. () => {},
  5. () => {}
  6. );
  7. // 2. 在路由文件中写入以下内容重写 push 和 replace
  8. // 2.1
  9. // 先把 VueRouter 原型对象的 push 保存一份
  10. let originPush = VueRouter.prototype.push;
  11. // 重写 push ( 第一个参数是使用 push 时的参数 )
  12. VueRouter.prototype.push = function(location, resolve, reject){
  13. if(resolve && reject){ // 如果在使用时使用了第一种方法,则还使用原来的 push 方法
  14. originPush.call(this, location, resolve, reject)
  15. } else {
  16. originPush.call(this, location, ()=>{}, ()=>{})
  17. }
  18. }
  19. // 先把 VueRouter 原型对象的 replace 保存一份
  20. let originReplace = VueRouter.prototype.replace;
  21. // 重写 replace ( 第一个参数是使用 replace 时的参数 )
  22. VueRouter.prototype.replace = function(location, resolve, reject){
  23. if(resolve && reject){ // 如果在使用时使用了第一种方法,则还使用原来的 push 方法
  24. originReplace.call(this, location, resolve, reject)
  25. } else {
  26. originReplace.call(this, location, ()=>{}, ()=>{})
  27. }
  28. }
  29. // 2.2
  30. // 也可以直接使用 catch 错误穿透接收
  31. const originalPush = VueRouter.prototype.push;
  32. VueRouter.prototype.push = function (location) {
  33. return originalPush.call(this, location).catch(err => err)
  34. }
  35. const originReplace = VueRouter.prototype.replace;
  36. VueRouter.prototype.replace = function (location) {
  37. return originReplace.call(this, location).catch(err => err)
  38. }