Vue深度嵌套路由中router-link的active状态匹配问题求助
我之前也碰到过完全一样的嵌套路由激活坑!问题出在Vue Router默认的包含匹配逻辑:只要当前路由路径包含<router-link>指向的路由段,就会给它加上激活类。比如你访问/staff/1/timeline时,所有指向business.staff.single(对应/staff/:id)的链接,不管id是1还是2,都会被判定为激活——exact属性在这里没用,因为它要求路径完全匹配,但你的实际路径是更深的嵌套路由,用了exact反而会让所有这些链接都不激活,完全不是你要的效果。
下面给你几个实用的解决方案,按推荐程度排序:
方案1:动态判断路由参数(最通用)
直接通过$route.params.id和链接对应的id做对比,动态绑定激活类。如果是单个链接,写法如下:
<router-link tag="li" :to="{ name: 'business.staff.single', props: {id: 1} }" :class="{ 'active': $route.params.id === 1 }" > <div class="avatar" style="background-image: url('url');"></div> <!-- 你的其他内容 --> </router-link>
如果是循环生成的员工列表链接,更灵活的写法:
<router-link v-for="staff in staffList" :key="staff.id" tag="li" :to="{ name: 'business.staff.single', props: {id: staff.id} }" :class="{ 'active': $route.params.id === staff.id }" > <div class="avatar" :style="{ backgroundImage: `url(${staff.avatarUrl})` }"></div> <div>{{ staff.name }}</div> </router-link>
这种方式不管你在/staff/:id还是它的子路由/staff/:id/timeline下,只要id匹配,对应的链接就会保持激活状态,完美适配嵌套场景。
方案2:用exact-active-class(仅适用于直接访问父路由的场景)
如果你的需求是只有直接访问/staff/:id时才激活链接,进入子路由后取消激活,可以用这个方案。首先确保你的路由配置是正确的嵌套结构:
const routes = [ { path: '/company', name: 'business', component: CompanyLayout, children: [ { path: 'staff/:id', name: 'business.staff.single', component: StaffDetail, children: [ { path: 'timeline', name: 'business.staff.single.timeline', component: StaffTimeline } ] } ] } ]
然后给<router-link>加上exact属性和exact-active-class:
<router-link tag="li" :to="{ name: 'business.staff.single', props: {id: 1} }" exact exact-active-class="active" > <!-- 你的内容 --> </router-link>
但注意,这种方式下当你进入/staff/1/timeline时,父链接会失去激活状态,如果你需要在子路由下保持父链接激活,就别用这个方案。
方案3:用v-slot自定义激活逻辑(Vue Router 2.6.0+)
如果你需要更精细的控制,可以通过router-link的v-slot获取默认的激活状态,再叠加自定义判断:
<router-link tag="li" :to="{ name: 'business.staff.single', props: {id: 1} }" v-slot="{ isActive, href }" > <a :href="href" :class="{ 'active': isActive && $route.params.id === 1 }"> <div class="avatar" style="background-image: url('url');"></div> <!-- 其他内容 --> </a> </router-link>
这里的isActive是Vue Router默认的包含匹配结果,我们再加上id相等的条件,就能精准控制激活状态了。
总的来说,方案1是最适合你场景的解决方案,不管路由嵌套多深,都能准确匹配对应的激活链接。
内容的提问来源于stack exchange,提问作者Sergiu

