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是/product
,to
是,那么是/product
的前缀,所以isActive
为true
)。
当我们给<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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。