如何在Nuxt 3中创建可自动生成层级结构的动态导航?
在Nuxt 3中动态生成带层级的导航数组
useRouter().getRoutes()返回的是扁平路由列表,确实不会自带层级关系,你可以通过解析路由的path字段手动构建树形导航结构,以下是具体实现方案:
核心思路
- 过滤掉Nuxt内部路由(如
/_nuxt、/api)和无效路由(如404),只保留pages目录下的页面路由 - 将每个路由转换为符合需求的导航项,并存入Map方便快速查找
- 根据路由路径的分段(如
/Page2/Page2a拆分为['Page2', 'Page2a']),将子导航项挂载到对应父节点的children数组中
完整实现代码
组件内直接实现
<template> <nav class="navigation"> <ul> <li v-for="item in navigationPaths" :key="item.to"> <NuxtLink :to="item.to">{{ item.label }}</NuxtLink> <!-- 渲染子导航 --> <ul v-if="item.children.length" class="sub-navigation"> <li v-for="child in item.children" :key="child.to"> <NuxtLink :to="child.to">{{ child.label }}</NuxtLink> </li> </ul> </li> </ul> </nav> </template> <script setup lang="ts"> import type { RouteRecordRaw } from 'vue-router' const router = useRouter() // 1. 过滤有效路由 const validRoutes = router.getRoutes().filter(route => { return !route.path.startsWith('/_nuxt') && !route.path.startsWith('/api') && route.path !== '/404' && route.path !== '/' // 若需包含根路由可移除该行 }) // 2. 构建导航树形结构 function buildNavigationTree(routes: RouteRecordRaw[]) { const tree: Array<{label: string; to: string; children?: Array<any>}> = [] const routeMap = new Map<string, typeof tree[0]>() // 先将所有路由转换为导航项存入Map routes.forEach(route => { const pathSegments = route.path.split('/').filter(seg => seg) // 优先使用页面自定义meta标签,其次用路由名(替换横杠为空格),最后用路径最后一段 const label = (route.meta.navigationLabel as string) || route.name?.toString().replace(/-/g, ' ') || pathSegments.at(-1) || 'Unnamed Page' const navItem = { label, to: route.path, children: [] as typeof tree } routeMap.set(route.path, navItem) }) // 将子导航项挂载到父节点 routes.forEach(route => { const pathSegments = route.path.split('/').filter(seg => seg) if (pathSegments.length > 1) { // 生成父路由路径 const parentPath = '/' + pathSegments.slice(0, -1).join('/') const parentNavItem = routeMap.get(parentPath) // 若父路由存在则挂载,否则作为顶级路由 if (parentNavItem) { parentNavItem.children.push(routeMap.get(route.path)) } else { tree.push(routeMap.get(route.path)) } } else { // 顶级路由直接加入树形结构 tree.push(routeMap.get(route.path)) } }) return tree } // 3. 生成最终导航数组 const navigationPaths = buildNavigationTree(validRoutes) </script>
自定义Page Meta优化标签
如果需要给页面设置自定义导航标签,可在对应页面的script中添加:
definePageMeta({ navigationLabel: '自定义页面标签' })
注意事项
- 若项目包含动态路由(如
/[id].vue),可在过滤路由时添加判断排除,或自定义动态路由的标签 - 该方案会自动监听路由变化,当pages目录新增页面时,热更新后导航数组会自动更新
内容的提问来源于stack exchange,提问作者wreckit
相关产品推荐
相关产品推荐

