Skip to content

路由匹配

动态路由匹配

很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数

例如像 /part/小明/part/小红 这样的 URL 需要映射到同一个路由,就可以像下面这样写。

js
// 这些都会传递给 `createRouter`
const routes = [
  // 动态字段以冒号开始
  { path: "/part/:id", component: () => import("../views/Part.vue") },
];

路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。因此,我们可以通过更新 Part 的模板来呈现当前的用户 ID

vue
<template>
  <div>
    <p>寻找伙伴</p>
    <div>User {{ $route.params.id }}</div>
  </div>
</template>

你可以在同一个路由中设置有多个 路径参数,它们会映射到 $route.params 上的相应字段。例如:

匹配模式匹配路径$route.params
/users/:username /users/eduardo { username: 'eduardo' }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: 'eduardo', postId: '123' }

除了 $route.params 之外,$route 对象还公开了其他有用的信息,如 $route.query(如果 URL 中存在参数)、$route.hash 等。你可以在 API 参考中查看完整的细节。

声明式导航

基础使用

目标:可用全局组件 router-link 来替代 a 标签

  1. vue-router 提供了一个全局组件 router-link
  2. router-link 实质上最终会渲染成 a 链接 to 属性等价于提供 href 属性 (to 无需#)
  3. router-link 提供了声明式导航高亮的功能 (自带类名)
vue
<template>
  <div>
    <div class="footer_wrap">
      <!--      <a href="#/find">发现音乐</a>-->
      <!--      <a href="#/my">我的音乐</a>-->
      <!--      <a href="#/part">朋友</a>-->
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/part">朋友</router-link>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

总结:链接导航,用 router-link 配合 to, 实现点击切换路由

跳转传参

目标:在跳转路由时,可以给路由对应的组件内传值

router-link 上的 to 属性传值,语法格式如下

  • /path?参数名=值
  • /path/值 – 需要路由对象提前配置 path: "/path/参数名"

对应页面组件接收传递过来的值

  • route.query.参数名
  • route.params.参数名

1、新建 views/Part2.vue - 接收路由上传递的参数和值

vue
<template>
  <div>
    <p>我的好友</p>
    <!-- query 查询?号后面的。params 是获取 url : 中的参数-->
    <p>人名 (path --> query): {{ route.query?.name }}</p>
    <p>人名 (?后参数 --> params): {{ route.params?.name }}</p>
  </div>
</template>

<script setup>
// 目标:声明式导航 - 基础使用
// 本质:vue-router 提供的全局组件 "router-link" 替代 a 标签
// 1. router-link  替代 a 标签
// 2. to 属性      替代 href 属性
// 好处:router-link 自带高亮的类名 (激活时类名)
// 3. 对激活的类名做出样式的编写
import { useRoute } from "vue-router";

const route = useRoute();
</script>

2、修改路由定义

js
const routes = [
  { path: "/find", component: () => import("../views/Find.vue") },
  { path: "/my", component: () => import("../views/My.vue") },
  { path: "/part", name: "Part", component: () => import("../views/Part.vue") },
  {
    path: "/part/:name", // 有:的路径代表要接收具体的值
    component: () => import("../views/Part2.vue"),
  },
];

3、修改 App.vue 进行跳转

vue
<template>
  <div>
    <div class="footer_wrap">
      <!--      <a href="#/find">发现音乐</a>-->
      <!--      <a href="#/my">我的音乐</a>-->
      <!--      <a href="#/part">朋友</a>-->
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/part">朋友</router-link>
      <router-link to="/part?name=小传">朋友 - 小传</router-link>
      <router-link to="/part/小智?name=小智2">朋友 - 小智</router-link>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

总结:

  • ?key=value$route.query.key 取值
  • /值 提前在路由规则 /path/:key$route.params.key 取值
  • query 是查询参数,paramspath 路径

在这个特定的场景中,我们在括号之间使用了自定义正则表达式,并将pathMatch 参数标记为可选可重复。这样做是为了让我们在需要的时候,可以通过将 path 拆分成一个数组,直接导航到路由:

捕获路由

常规参数只匹配 url 片段之间的字符,用 / 分隔。如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式,在 路径参数 后面的括号中加入 正则表达式 :

js
const routes = [
  // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
  { path: "/:pathMatch(.*)*", name: "NotFound", component: NotFound },
  // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
  { path: "/user-:afterUser(.*)", component: UserGeneric },
];

案例 - 404 页面

默认给一个 404 页面

语法:路由最后,path 匹配*(任意路径) – 前面不匹配就命中最后这个,显示对应组件页面

1、创建 NotFound 页面

vue
<template>
  <div>404 资源不存在</div>
</template>

2、在 src/router/index.js - 修改路由配置

js
const routes = [
  // ...省略了其他配置
  // 404 在最后 (规则是从前往后逐个比较 path)
  {
    path: "/:pathMatch(.*)*",
    component: () => import("../views/NotFound.vue"),
  },
];

vue-router 错误页面

总结:如果路由未命中任何规则,给出一个兜底的 404 页面