Code前端首页关于Code前端联系我们

Vue Router里的exact是干啥的?怎么用?

terry 2小时前 阅读数 5 #Vue
文章标签 Vue Router;exact

刚接触Vue Router的时候,很多同学会疑惑「exact属性是干啥的?不用它为啥路由匹配总出问题?」其实exact是Vue Router里控制路由精准匹配的关键属性,理解它能帮我们解决不少导航栏选中、页面跳转错乱的问题,今天就从作用、用法、场景这些角度,把exact讲明白~

exact解决了啥核心问题?

先想个场景:你做了个导航栏,有「首页」(对应路径)和「产品」(对应路径/product),默认情况下,当你点击进入/product页面时,会发现「首页」的导航按钮也被高亮了!这不是Bug,而是Vue Router默认的路由匹配规则在起作用——模糊匹配(包含匹配)

Vue Router默认会把「当前路径是否包含目标路径」作为匹配依据,比如路径是/product,它包含了(首页的路径),所以首页的<router-link>会被判定为“激活”,导致高亮错误。

而exact的作用,就是把这种「包含匹配」改成精准匹配:只有当「当前路径和目标路径完全一模一样」时,才判定为激活,回到刚才的例子,给首页的<router-link>加上exact,访问/product时,首页就不会被错误高亮了,只有访问时才会高亮。

exact怎么用?(代码+场景演示)

exact是<router-link>组件的一个布尔属性,用法很简单——在需要精准匹配的<router-link>上添加exact即可,看个简单例子:

<template>
  <nav>
    <!-- 首页需要精准匹配,加exact -->
    <router-link to="/" exact>首页</router-link>
    <router-link to="/product">产品</router-link>
  </nav>
</template>

这里有两个关键点要注意:

  • 只作用于<router-link>的“激活状态”:exact不影响路由跳转是否成功(比如你访问不存在的路径会404,这是路由配置的事),它只控制「这个<router-link>该不该高亮」。
  • 编程式导航不涉及exact:比如用this.$router.push('/')跳转,这是直接修改路径,和exact没关系,exact只管<router-link>的视觉激活和逻辑判断(比如isActive)。

再举个反例感受下:如果首页没加exact,当你访问/product时,首页的<router-link>会因为“路径包含”被激活,按钮高亮;加了exact后,只有路径完全等于时才高亮,访问/product时首页按钮就不亮了,产品按钮才亮——这才是用户预期的效果。

哪些场景必须用exact?

不是所有场景都要加exact,但遇到这三类情况,exact几乎是“必选项”:

导航栏高亮的精确控制

导航栏是最常见的场景,比如顶部导航有「首页」()、「博客」(/blog)、「(/about),如果不加exact,访问/blog时,「首页」的<router-link>会因为路径包含而被激活,导致两个按钮同时高亮,用户根本分不清自己在哪页。

解决方法很直接:给「首页」的<router-link>加上exact,确保只有访问时才高亮,其他子路径(如/blog/about)不会干扰。

多级路由嵌套时的边界控制

比如做用户系统,有「用户列表」(/user)和「用户详情」(/user/123),这时候,/user是一级路由,/user/123是二级嵌套路由,如果不给/user<router-link>加exact,当你进入/user/123时,/user<router-link>也会被激活(因为路径包含/user),导致“用户列表”按钮一直高亮,哪怕你在看详情页。

这时候加exact,让/user<router-link>只有在访问/user(列表页)时才高亮,进入/user/123(详情页)时就不亮了,视觉和逻辑都更合理。

首页与子路由的冲突

很多项目的首页是,同时有子路由(比如/blog/shop),当用户访问/blog时,首页的<router-link>默认会因为“路径以开头”被激活,导致首页按钮一直亮着,完全违背“当前在博客页”的预期,这时候给首页加exact,就能让首页只在访问时高亮,进子路由时自动取消高亮。

exact和其他匹配规则咋配合?

理解exact时,得和Vue Router的其他机制区分开,避免混淆:

active-class的关系

<router-link>active-class是用来自定义激活时的CSS类名的,而exact决定的是「什么时候算激活」——加了exact,只有精准匹配时才会添加active-class;没加的话,包含匹配时就会加,所以exact是“激活规则”,active-class是“激活后的样式”,两者是逻辑和表现的关系。

和通配符的区别

路由配置里的是“匹配所有路径”(比如{ path: '*', component: 404 }),属于兜底匹配;而exact是“必须完全匹配”,属于精准限制,一个是“全收”,一个是“严卡”,逻辑完全相反。

和路由配置path的区别

路由配置里的path是用来匹配URL路径,决定渲染哪个组件;而exact是<router-link>的属性,决定这个链接该不该高亮,举个例子:路由配置path: '/user'对应User组件,不管有没有exact,访问/user都会渲染User组件;但<router-link to="/user">的高亮状态,由exact决定(加了exact,只有访问/user时高亮;没加的话,访问/user/123也会高亮)。

不用exact容易踩的坑?

很多同学开发时没注意exact,结果遇到这些“玄学问题”:

导航栏“串台”高亮

前面说的导航栏多个按钮同时高亮,比如有、/news/news/detail三个路径,没加exact的话,访问/news/detail时,和/news<router-link>都会因为“路径包含”被激活,三个按钮亮两个,用户直接懵圈。

逻辑依赖激活状态时出错

有些场景会用<router-link>isActive属性做逻辑判断(比如根据是否激活显示不同按钮),如果没加exact,isActive的判断逻辑是“包含匹配”,导致逻辑错误,比如想“只有在首页时显示登录按钮”,没加exact的话,进/blog页时isActive还是true,登录按钮关不掉。

嵌套路由视觉混乱

多级路由下,父路由的<router-link>如果没加exact,会一直高亮,哪怕进入子路由,比如电商项目的“商品分类”(/category)和“商品详情”(/category/1001),没加exact的话,进详情页时“商品分类”按钮还亮着,用户以为还在分类页,体验很差。

实战:用exact优化导航栏高亮

拿一个简单的博客项目举例,需求是:导航栏有「首页」「文章」「,点击对应按钮高亮,且互不干扰。

路由配置(router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Articles from '../views/Articles.vue'
import About from '../views/About.vue'
const routes = [
  { path: '/', component: Home },
  { path: '/articles', component: Articles },
  { path: '/about', component: About }
]
const router = createRouter({
  history: createWebHistory(),
  routes
})
export default router

导航栏组件(Navbar.vue

先看不加exact的情况:

<template>
  <nav class="navbar">
    <router-link to="/">首页</router-link>
    <router-link to="/articles">文章</router-link>
    <router-link to="/about">lt;/router-link>
  </nav>
</template>
<style scoped>
.navbar a {
  margin: 0 10px;
  text-decoration: none;
}
.router-link-active {
  color: red; /* 激活时变红 */
}
</style>

这时访问/articles页面,你会发现「首页」和「文章」的文字都变红了!因为/articles的路径包含,所以首页的<router-link>也被判定为激活。

加exact修复

只需要给「首页」的<router-link>加上exact

<template>
  <nav class="navbar">
    <router-link to="/" exact>首页</router-link>
    <router-link to="/articles">文章</router-link>
    <router-link to="/about">lt;/router-link>
  </nav>
</template>

现在再访问/articles,只有「文章」按钮变红;访问时,只有「首页」按钮变红——这才是正常的导航栏高亮逻辑!

exact的原理是啥?(深入理解)

想彻底搞懂exact,得看<router-link>的内部逻辑,Vue Router的<router-link>组件,会通过isActive方法判断是否激活。

默认情况下,isActive的判断逻辑是:当前路由的path是否以to的路径为前缀(比如当前path是/productto是,那么是/product的前缀,所以isActivetrue)。

当我们给<router-link>加上exact属性后,isActive的判断逻辑变成:当前路由的path是否和to的路径完全相等(只有path === to的路径时,isActive才为true)。

exact本质是修改了<router-link>激活状态的判断规则,让“包含匹配”变成“全等匹配”,但它不影响路由本身的跳转逻辑(路由跳转是看路由配置里的path和URL是否匹配,和exact没关系)。

exact的核心价值

exact是Vue Router里一个小而关键的属性,它解决的是「路由激活状态的精准控制」问题,记住这几点:

  • 默认是包含匹配,exact改成精准匹配
  • 只作用于<router-link>激活状态(高亮、active-class等);
  • 导航栏、多级路由、首页子路由这些场景,必须用exact避免视觉和逻辑错误。

下次再遇到导航栏高亮错乱、路由激活状态不对的问题,先想想是不是exact没加对~如果这篇文章帮你理清了exact的用法,不妨动手在项目里试试,感受精准匹配的魅力~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门