You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Nuxt 3中创建可自动生成层级结构的动态导航?

在Nuxt 3中动态生成带层级的导航数组

useRouter().getRoutes()返回的是扁平路由列表,确实不会自带层级关系,你可以通过解析路由的path字段手动构建树形导航结构,以下是具体实现方案:

核心思路

  1. 过滤掉Nuxt内部路由(如/_nuxt、/api)和无效路由(如404),只保留pages目录下的页面路由
  2. 将每个路由转换为符合需求的导航项,并存入Map方便快速查找
  3. 根据路由路径的分段(如/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:41:23