## 第 2 章：路由与页面（文件路由系统）

本章将完整学习 Nuxt 4 **约定式文件路由**，这是框架最核心、最常用的能力，全程包含可直接**运行的代码 + 实战步骤**，学完即可搭建项目完整路由架构。

### 2.1 基础路由：pages 目录与 index.vue

Nuxt 4 会自动扫描 app/pages/ 目录下的 .vue 文件生成路由，**无需配置路由表**。

#### **核心规则**

- app/pages/index.vue → 首页 /

- app/pages/about.vue → /about

- app/pages/books/index.vue → /books

#### **实战代码**

1，修改入口文件

```vue

<template>

<div>

<NuxtPage />

</div>

</template>

```

2，首页页面

app/index.vue

```vue

<template>

<div>

<h1>Diibook实战教程网 🏠</h1>

<p>欢迎来到 Nuxt 4 全栈实战项目</p>

</div>

</template>

```

3，关于页页面

app/pages/about.vue

```vue

<template>

<div>

<h1>About</h1>

</div>

</template>

```

#### **实战步骤**

1，在 pages 目录创建 index.vue、about.vue

2，运行 yarn dev

3，访问：

首页：http://localhost:3000/

关于页：http://localhost:3000/about

### 2.2 动态路由：[id].vue 与参数获取

动态路由用于**详情页**（商品、文章、用户），文件名用 [参数名] 定义。

#### **核心规则**

- app/pages/books/[id].vue → /books/1、/books/100

#### **实战代码**

app/pages/books/[id].vue

```vue

<template>

<div>

<h1>图书详情页</h1>

<p>当前图书 ID：{{ id }}</p>

</div>

</template>

<script setup>

// 获取路由实例

const route = useRoute()

// 获取动态路由参数 id

const id = route.params.id

</script>

```

#### 实战演练

- 1，创建目录 books，在里面新建 [id].vue

- 2，浏览器访问：http://localhost:3000/books/666

- 3，页面会自动显示：当前图书 ID：666

### 2.3 嵌套路由：文件夹嵌套与父页面 [...slug].vue

嵌套路由用于**带公共布局的页面**（如后台、个人中心）等。

#### 1，基础嵌套路由

规则：**父文件 + 子文件夹同名**

- 父页面：app/pages/articles.vue

- 子页面：app/pages/articles/list.vue

父页面必须放置 <NuxtPage /> 显示子页面：

app/pages/articles.vue

```vue

<template>

<div>

<h1>文章列表页</h1>

<NuxtPage />

</div>

</template>

```

子页面 app/pages/articles/list.vue

```vue

<template>

<div>文章列表内容</div>

</template>

```

#### 2，全匹配路由 [...slug].vue

用于捕获多级路由 / 404 / 分类页等。

- app/pages/[slug].vue → /404

- app/pages/category/[slug].vue → /category/tech、/category/finance

#### **实战代码**

app/pages/[...slug].vue

```vue

<template>

<div>

<h1>全匹配路由</h1>

<p>路径片段：{{ slug }}</p>

</div>

</template>

<script setup>

const route = useRoute()

const slug = route.params.slug

</script>

```

#### 实战演练

- 1，创建嵌套路由 articles.vue + articles/list.vue

- 2，访问 /articles/list 查看嵌套效果

- 3，访问 /a/b/c/d 查看 [...slug].vue 捕获效果

### 2.4 路由跳转：<NuxtLink> 与 navigateToNuxt

Nuxt 提供两种无刷新跳转，不会重新加载页面。

#### 1. 标签跳转 <NuxtLink>（推荐）

app/pages/index.vue

```vue

<template>

<div>

<h1>首页</h1>

<!-- 普通跳转 -->

<NuxtLink to="/about">关于我们</NuxtLink>

<!-- 动态路由跳转 -->

<NuxtLink to="/books/100">查看小册 id=100</NuxtLink>

</div>

</template>

```

#### 2. 编程式跳转 navigateTo

```vue

<template>

<button @click="goToBook">跳转到小册详情</button>

</template>

<script setup>

const goToBook = () => {

// 跳转到固定页面

navigateTo('/about')

// 跳转到动态路由

navigateTo('/books/200')

// 打开外部链接

// navigateTo('https://juejin.cn', { external: true })

}

</script>

```

合并代码：app/pages/index.vue

```vue

<template>

<div>

<h1>Diibook实战教程网 🏠 首页</h1>

<p>欢迎来到 Nuxt 4 全栈实战项目</p>

<!-- 普通跳转 -->

<NuxtLink to="/about">关于我们</NuxtLink>

<br />

<!-- 动态路由跳转 -->

<NuxtLink to="/books/100">查看小册 id=100</NuxtLink>

<br />

<!-- 编程式跳转 -->

<button @click="goToAbout">跳转到关于我们</button>

<br />

<button @click="goToBook(100)">跳转到小册详情页</button>

<br />

<button @click="goToExternal">打开外部链接</button>

</div>

</template>

<script setup>

const goToBook = (id) => {

navigateTo(`/books/${id}`)

}

const goToAbout = () => {

navigateTo('/about')

}

const goToExternal = () => {

navigateTo('https://www.baidu.com', { external: true })

}

</script>

```

#### 实战演练

- 1，在首页添加多个 <NuxtLink>

- 2，编写点击事件，使用 navigateTo 跳转到动态路由

- 3，测试无刷新跳转效果

### 2.5 路由验证：definePageMeta

用于给页面设置标题、布局、权限、缓存，写在 script setup 最顶部。

#### 代码示例

```js

<script  setup>

// 页面配置

definePageMeta({

// 页面标题

title: 'Diibook实战教程网 - 首页',

// 使用的布局

layout: 'default',

// 是否需要登录（自定义标记）

requiresAuth: false,

// 是否缓存页面

keepalive: false

})

</script>

<template>

<div>页面内容</div>

</template>

```

#### **实战代码**

pages/books/[id].vue

```js

<template>

<div>

<h1>图书详情页</h1>

<p>当前图书 ID：{{ id }}</p>

</div>

</template>

<script  setup  lang="js">

// 获取路由实例

const route = useRoute()

// 获取动态路由参数 id

const id = route.params.id

definePageMeta({

// 文章Id必须是数字

path: '/books/:id(\\d+)',

})

</script>

```

#### 实战演练

- 1，访问 http://localhost:3000/books/100

- 2，访问 http://localhost:3000/books/abc，会跳转到 404 页面

### 2.6 404 页面与全局错误处理

#### 1. 404 页面（未找到页面）

app/pages/[...slug].vue

```js

<template>

<div  class="text-center p-10">

<h1>404 ❌</h1>

<p>您访问的页面不存在</p>

<br  />

<p>路径片段：{{ slug }}</p>

<NuxtLink  to="/">返回首页</NuxtLink>

</div>

</template>

<script  setup>

const route = useRoute()

const slug = route.params.slug

</script>

```

#### 2. 全局错误页面 error.vue

app/error.vue，捕获所有异常（接口、服务端、渲染错误）

```js

<template>

<div  class="p-10">

<h2>请求出错了 {{ error.statusCode }}</h2>

<p>{{ error.message }}</p>

<button  @click="retry">重试</button>

</div>

</template>

<script  setup>

const props = defineProps(['error'])

const retry = () => refreshNuxtData()

</script>

```

#### 实战演练

- 1，访问一个不存在地址，查看 404

- 2，手动制造错误，查看全局错误页 (可以先删除[...slug].vue 进行测试)

### 本章总结

1. 基础路由：pages/ 文件自动生成路径

2. 动态路由：[id].vue 获取详情参数

3. 嵌套路由：父页面 + 子文件夹 + <NuxtPage>

4. 路由跳转：<NuxtLink> + navigateTo

5. 页面配置：definePageMeta 设置标题、布局、权限

6. 异常页面：[...slug].vue 404 + error.vue 全局错误