Vue Router嵌套路由激活状态保持问题:访问子路由时保持父级侧边栏菜单项激活
解决Vue Router子路由下父级侧边栏保持激活状态的问题
这个问题在Vue项目里挺常见的,核心原因就是你给<router-link>加了exact属性——它会强制要求路径完全匹配才会触发激活状态,而/projects/10和/projects显然不是完全一致的路径,所以父级菜单就自动失活了。
下面给你几个实用的解决办法,按推荐程度排序:
方法1:移除exact属性(最简便直接)
直接把<router-link>上的exact删掉就行:
<router-link :to="{ name: 'projects' }" class="sidenav-menu-item" tag="li" > <a :style="currentBackground"> <icon class="icon" width="19" height="19" type="properties"/> <span>{{ $t('pages.projects.title') }}</span> </a> </router-link>
Vue Router默认是包含式匹配,也就是说当你访问/projects/:id时,它会自动匹配所有路径以/projects开头的路由规则,对应的router-link就会自动加上激活类。这种方法最适合你的场景,因为父路由和子路由的路径层级关系很清晰,不会有冲突。
方法2:手动控制激活状态(适合有路由冲突的场景)
如果因为项目里其他路由规则的限制,不能直接移除exact,可以通过计算属性手动判断当前路由是否属于父路由的子路由,从而控制激活状态:
首先在Sidenav.vue里定义一个计算属性:
computed: { isProjectsActive() { // 判断当前路由路径是否以/projects开头 return this.$route.path.startsWith('/projects'); } }
然后修改<router-link>,用class绑定来应用激活样式:
<router-link :to="{ name: 'projects' }" class="sidenav-menu-item" tag="li" :class="{ 'your-active-class': isProjectsActive }" > <a :style="currentBackground"> <icon class="icon" width="19" height="19" type="properties"/> <span>{{ $t('pages.projects.title') }}</span> </a> </router-link>
记得把your-active-class换成你项目里实际使用的激活样式类名。
方法3:利用路由meta配置(适合复杂路由场景)
如果你的路由结构比较复杂,还可以给父路由和子路由添加统一的标识,通过这个标识来判断激活状态:
先修改路由配置:
{ path: '/projects', name: 'projects', meta: { title: 'Projects', documentTitle: '*pages.projects.title', empty: true, activeGroup: 'projects' // 添加统一激活组标识 }, component: () => import('@/views/Projects.vue'), }, { path: '/projects/:id', name: 'projects-keys', meta: { title: 'Projects Keys', empty: true, activeGroup: 'projects' // 和父路由用同一个标识 }, component: () => import('@/views/ProjectsKeys.vue'), },
然后在Sidenav.vue里计算激活状态:
computed: { isProjectsActive() { return this.$route.meta.activeGroup === 'projects'; } }
最后同样通过class绑定来应用激活样式,和方法2的模板部分一致。
内容的提问来源于stack exchange,提问作者GPiter
相关产品推荐
相关产品推荐

