文件路由与导航
🎯 引言
学会这篇文章,你能用“文件即路由”的方式搭建 Nuxt 应用的多页面结构。你会掌握普通页面、动态参数页面、嵌套路由的写法,学会用 <NuxtLink> 做页面跳转,并读取当前路由信息。
🧱 文件即路由
在 Nuxt 里,路由不是写在 router/index.js 里,而是由 app/pages/ 目录下的文件结构自动生成的。
假设目录结构如下:
pages/
├─ index.vue // 首页 /
├─ about.vue // /about
├─ user/
│ ├─ index.vue // /user
│ ├─ profile.vue // /user/profile
│ ├─ [id].vue // /user/:id
Nuxt 会自动生成对应的路由表,你不需要手动配置 vue-router。
pages/ 想象成网站的“目录树”:文件夹就是路径层级,.vue 文件就是最终页面。📄 普通页面
最简单的页面就是直接在 pages/ 下创建一个 .vue 文件。
<template>
<div>
<h1>关于我们</h1>
<p>这是关于页面</p>
</div>
</template>
访问 /about 就能看到上面的内容。
pages/index.vue 表示该目录下的默认首页,对应路径 /。🔢 动态路由
当 URL 中某一段是不固定的,比如 /user/123、/user/456,就需要用到动态路由。Nuxt 用方括号 [] 表示动态段。
<!-- app/pages/user/[id].vue -->
<template>
<div>
<h1>用户详情</h1>
<p>用户 ID:{{ route.params.id }}</p>
</div>
</template>
<script setup>
const route = useRoute();
</script>
访问 /user/123 时,route.params.id 的值就是 '123'。
useRoute() 返回的是当前路由对象,里面的 params 都是字符串。如果需要做数学运算,记得用 Number(route.params.id) 转换。🪺 嵌套路由
如果希望页面有公共布局,中间部分内容随子路由变化,可以用嵌套路由。
目录结构:
pages/
├─ user.vue // 父路由布局 /user
├─ user/
│ ├─ index.vue // /user
│ ├─ settings.vue // /user/settings
│ ├─ [id].vue // /user/:id
如果 pages/user.vue 存在,它会作为父路由布局:
<template>
<div>
<h2>用户中心</h2>
<NuxtPage />
</div>
</template>
访问 /user/settings 时,会渲染 user.vue 的公共结构,中间再嵌入 user/settings.vue 的内容。
user.vue 和 user/),Nuxt 就知道它们是嵌套关系。🔗 页面导航
Nuxt 提供 <NuxtLink> 组件替代原生的 <a> 标签,用来在应用内部跳转。它会智能使用前端路由,不会整页刷新。
<template>
<div>
<h1>首页</h1>
<NuxtLink to="/about">去关于页</NuxtLink>
<NuxtLink :to="`/user/${userId}`">去用户详情</NuxtLink>
</div>
</template>
<script setup>
const userId = 123;
</script>
<a> 标签,比如 <a href="https://nuxt.com">官网</a>。<NuxtLink> 更适合站内路由。🧭 获取当前路由信息
除了 useRoute() 读取参数,你还可以用它获取路径、查询字符串等信息。
<template>
<div>
<p>搜索关键词:{{ route.query.keyword }}</p>
</div>
</template>
<script setup>
const route = useRoute();
</script>
访问 /search?keyword=nuxt 时,页面会显示“搜索关键词:nuxt”。
🚫 404 页面
Nuxt 允许你自定义 404 页面。最简单的方式是在 pages/ 下创建一个全匹配动态路由文件。
全匹配动态路由的写法是 [...参数名].vue,三个点表示“捕获剩余所有路径段”,参数名 可以自定义,常见写法有 [...slug].vue、 [...path].vue、 [...catchAll].vue。
<!-- app/pages/[...slug].vue -->
<template>
<div>
<h1>404 - 页面不存在</h1>
<NuxtLink to="/">返回首页</NuxtLink>
</div>
</template>
slug 不是固定名字,只是参数名。你可以改成 path、catchAll 等任何合法标识符。访问 /aaa/bbb 时,route.params.slug 会得到数组 ['aaa', 'bbb']。🧾 小节总结
- Nuxt 通过
pages/目录自动生成路由,文件路径就是 URL 路径。 index.vue表示目录默认页,[id].vue表示动态路由参数。- 同名
xxx.vue+xxx/文件夹可实现嵌套路由,公共结构里用<NuxtPage />渲染子页面。 - 站内导航用
<NuxtLink>,外部链接用<a>。 useRoute()可以读取当前路由参数、查询字符串等信息。[...参数名].vue是全匹配动态路由,常用来实现自定义 404 页面。
❓ 知识问答
Q1:pages/user/[id].vue 和 pages/user-[id].vue 有什么区别?
pages/user/[id].vue 生成 /user/:id;pages/user-[id].vue 生成 /user-:id,比如 /user-123。
Q2:动态路由参数一定是字符串吗?
是的,route.params.xxx 和 route.query.xxx 都是字符串,需要数字时要手动转换。
Q3:<NuxtLink> 和 <a> 在站内外跳转上怎么选?
站内跳转用 <NuxtLink>,体验更好(不会整页刷新);站外跳转或下载链接用 <a>。
Q4:嵌套路由时,父组件必须写 <NuxtPage /> 吗?
是的,否则子路由的内容不会渲染出来。
Q5:[...slug].vue 里的 slug 是固定写法吗?
不是固定的,它是参数名,可以改成 path、catchAll 等。访问 /a/b 时,route.params.你写的名字 会得到数组 ['a', 'b']。
🧪 小练习
在 Nuxt 项目中完成以下路由结构:
pages/
├─ index.vue
├─ product/
│ ├─ index.vue // /product
│ ├─ [id].vue // /product/:id
- 在
product/index.vue中列出两个商品链接,分别指向/product/1和/product/2。 - 在
product/[id].vue中读取route.params.id并显示“商品 ID:x”。 - 添加一个返回
/product列表的<NuxtLink>。
<!-- app/pages/product/[id].vue -->
<template>
<div>
<h1>商品详情</h1>
<!-- 请在这里显示商品 ID -->
<!-- 请在这里添加返回列表的链接 -->
</div>
</template>
<script setup>
// 请在这里获取当前路由
</script>
🎉 恭喜你已经掌握了 Nuxt 的文件路由系统!下一篇我们会学习 Nuxt 中最常用的数据获取方式:useFetch 和 useAsyncData。
