exercises.md 4.8 KB
Newer Older
Z
zhaoss 已提交
1 2
# 动态路由

Z
zhaoss 已提交
3
 <div style="color: pink;font-size:24px">小常识:</div>
Z
zhaoss 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
<br>

**动态路由**
对路由的添加通常是通过 routes 选项来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由。具有可扩展接口(如 Vue CLI UI )这样的应用程序可以使用它来扩展应用程序。

**添加路由**
动态路由主要通过两个函数实现。`router.addRoute() 和 router.removeRoute()`。它们只注册一个新的路由,也就是说,如果新增加的路由与当前位置相匹配,就需要你用 `router.push() 或 router.replace()` 来手动导航,才能显示该新路由。我们来看一个例子:

想象一下,只有一个路由的以下路由:

```javascript
const router = createRouter({
  history: createWebHistory(),
  routes: [{ path: '/:articleName', component: Article }],
})
```

进入任何页面,`/about,/store`,或者 `/3-tricks-to-improve-your-routing-code` 最终都会呈现 Article 组件。如果我们在 /about 上添加一个新的路由:

```javascript
router.addRoute({ path: '/about', component: About })
```

页面仍然会显示 Article 组件,我们需要手动调用 `router.replace()` 来改变当前的位置,并覆盖我们原来的位置(而不是添加一个新的路由,最后在我们的历史中两次出现在同一个位置):

```javascript
router.addRoute({ path: '/about', component: About })
// 我们也可以使用 this.$route 或 route = useRoute() (在 setup 中)
router.replace(router.currentRoute.value.fullPath)
```

记住,如果你需要等待新的路由显示,可以使用 await router.replace()。

在导航守卫中添加路由#
如果你决定在导航守卫内部添加或删除路由,你不应该调用 `router.replace()`,而是通过返回新的位置来触发重定向:

```javascript
router.beforeEach(to => {
  if (!hasNecessaryRoute(to)) {
    router.addRoute(generateRoute(to))
    // 触发重定向
    return to.fullPath
  }
})
```

上面的例子有两个假设:第一,新添加的路由记录将与 to 位置相匹配,实际上导致与我们试图访问的位置不同。第二,`hasNecessaryRoute()` 在添加新的路由后返回 false,以避免无限重定向。

因为是在重定向中,所以我们是在替换将要跳转的导航,实际上行为就像之前的例子一样。而在实际场景中,添加路由的行为更有可能发生在导航守卫之外,例如,当一个视图组件挂载时,它会注册新的路由。

**删除路由**
有几个不同的方法来删除现有的路由:

通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:

```javascript
router.addRoute({ path: '/about', name: 'about', component: About })
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other })
```

通过调用 router.addRoute() 返回的回调:

```javascript
const removeRoute = router.addRoute(routeRecord)
removeRoute() // 删除路由如果存在的话
```

当路由没有名称时,这很有用。
通过使用 router.removeRoute() 按名称删除路由:

```javascript
router.addRoute({ path: '/about', name: 'about', component: About })
// 删除路由
router.removeRoute('about')
```

需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。
当路由被删除时,所有的别名和子路由也会被同时删除

**添加嵌套路由**
要将嵌套路由添加到现有的路由中,可以将路由的 name 作为第一个参数传递给 `router.addRoute()`,这将有效地添加路由,就像通过 children 添加的一样:

```javascript
router.addRoute({ name: 'admin', path: '/admin', component: Admin })
router.addRoute('admin', { path: 'settings', component: AdminSettings })
这等效于

router.addRoute({
  name: 'admin',
  path: '/admin',
  component: Admin,
  children: [{ path: 'settings', component: AdminSettings }],
})
```

**查看现有路由**
`Vue Router` 提供了两个功能来查看现有的路由:

```javascript
router.hasRoute()检查路由是否存在
router.getRoutes()获取一个包含所有路由记录的数组
```

<br>

 <div style="color: pink;">小测试:</div >

根据上方小常识,以下关于动态路由的说法不正确的是?<br/><br/>

## 答案

路径参数不接受 正则表达式

## 选项

### A

动态路由的路径参数 用冒号 : 表示

### B

要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性

### C

当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来