Skip to content

匹配当前路由的链接

应用程序通常都会有一个渲染 RouterLink 列表的导航组件。我们也许想对这个列表中匹配当前路由的链接进行视觉区分。

RouterLink 组件会为匹配当前路由的链接添加两个 CSS 类,router-link-activerouter-link-exact-active。要理解它们之间的区别,我们首先需要了解 Vue Router 如何判断一个链接是匹配当前路由的。

连接在什么时候匹配当前路由

  1. 它与当前路径匹配相同的路由记录(即配置的路由)
  2. 它的params与当前路径的相同

如果你使用了嵌套路由,任何指向祖先路由的链接也会被认为是匹配当前路由的,只要相关的 params 匹配。

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        path: 'profile',
        component: UserProfile,
      },
      {
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]
html
<router-link to="/user/123" active-class="active">用户概览</router-link>
<router-link to="/user/123/posts" active-class="active">用户帖子</router-link>

如果当前路由为 /user/123/posts 那么匹配的链接为;

  • /user/123 (父路由)
  • /user/123/posts (完全匹配)
  • /user/123/profile (同级路由)

这三个路由的params都是{id:123}所以都会匹配到,如果想要严格只匹配相同的路径,可以使用exact属性

html
<router-link to="/user/123" exact active-class="active">用户概览</router-link>

然而,匹配与否与query参数无关,即使它也是给子路由传递参数的

如果路由使用了别名,虽然URL上显示的与匹配规则无关联,但是只要是解析到了相同的路由记录和params同样会被人为匹配.这其实意味着,匹配与否其实决定于路由配置声明的path.同理,在重定向时,匹配的根据也不会是重定向的路径

精确匹配当前路由的链接

js
const routes = [
  {
    path: '/user/:username',
    component: User,
    children: [
      {
        path: 'role/:roleId',
        component: Role,
      },
    ],
  },
]
html
<RouterLink to="/user/erina"> User </RouterLink>
<RouterLink to="/user/erina/role/admin"> Role </RouterLink>

如果当前路径是 /user/erina/role/admin,那么这两个链接都会被认为是匹配当前路由的,因此 router-link-active 类会应用于这两个链接。但只有第二个链接会被认为是精确的,因此只有第二个链接会有 router-link-exact-active 类。

activeexact-active 应用规则

  • router-link-active
    • 当链接的目标路由 或任何其嵌套路由 匹配当前路径时,这个类会被应用。
    • 在上面的例子中:
      • /user/erina/user/erina/role/admin 的父路由,因此第一个链接会匹配。
      • /user/erina/role/admin 是当前路径的精确匹配,因此第二个链接也会匹配。
    • 所以两个链接都会有 router-link-active 类。
  • router-link-exact-active
    • 只有当链接的目标路由 完全匹配当前路径(包括所有动态段和查询参数(params))时,这个类才会被应用。
      • 在上米艾尼的例子中 :
        • 第一个链接的目标是 /user/erina,而当前路径是 /user/erina/role/admin,不是完全匹配,所以不会应用。
        • 第二个链接的目标是 /user/erina/role/admin,与当前路径完全一致,所以会应用。
      • 因此只有第二个链接会有 router-link-exact-active 类。

关键区别

  • router-link-active 是“模糊匹配”(包含嵌套路由)。
  • router-link-exact-active 是“精确匹配”(路径必须完全一致)。

配置类名

RouterLink 组件有两个属性,activeClassexactActiveClass,可以用来更改应用的类名:

html
<RouterLink activeClass="border-indigo-500" exactActiveClass="border-indigo-700"></RouterLink>

默认的类名也可以通过传递 linkActiveClasslinkExactActiveClass 选项给 createRouter() 来全局更改:

js
const router = createRouter({
  linkActiveClass: 'border-indigo-500',
  linkExactActiveClass: 'border-indigo-700',
  // ...
})