首页/13

13章:Next.js基础:让博客跑起来

从静态类型到动态页面,学习Next.js框架的核心概念

60分钟
4个学习目标

学习目标

  • 1理解Next.js是什么,为什么它是TypeScript的最佳搭档
  • 2掌握App Router的文件系统路由
  • 3学会创建页面和布局
  • 4理解服务器组件和客户端组件的区别

回顾与问题引入

在前面的章节中,我们已经掌握了TypeScript的核心能力:类型系统、接口、泛型、工具类型。你可能会问——学了这么多类型知识,怎么用到真实的网站里?

这就是本章要解决的问题。

想象一下:你已经设计好了博客的数据类型(Post、User、Comment),现在需要把这些类型变成一个真正能访问的网站。你需要:

  • 一个首页展示文章列表
  • 点击文章进入详情页
  • 一个"写文章"的页面

传统的方式是:用一个前端框架(比如React)做页面,再用一个后端框架(比如Express)做API,分别部署。这就像开一家餐厅,厨房和餐厅要分两个地方——客人点餐要跑来跑去,效率很低。

Next.js就是那个"前厅后厨一体化"的解决方案。

Next.js是什么?

简单来说,Next.js是基于React的全栈框架。如果说React是一套"装修材料",那Next.js就是一套"精装房"——React能做的它都能做,还额外送你很多开箱即用的功能。

一个生活化的类比:

| 概念 | 类比 | |------|------| | React | 毛坯房(需要自己装修) | | Next.js | 精装房(拎包入住) | | 页面路由 | 房间的门牌号 | | 布局(Layout) | 每个房间都有的标配家具 | | API路由 | 房间里的服务按钮 |

Next.js的核心特性:

  • 文件系统路由:文件路径就是网址,不需要手动配置
  • 服务器端渲染(SSR):页面在服务器上生成,SEO友好
  • 静态站点生成(SSG):提前生成页面,访问速度极快
  • API路由:前后端写在一个项目里
  • 自动代码分割:只加载当前页面需要的代码
  • TypeScript原生支持:零配置就能用TS

创建Next.js项目

bash
加载中...

文件系统路由:路径即页面

这是Next.js最巧妙的设计之一:你创建的文件路径,就是网站的URL路径

不需要写任何路由配置文件,不需要import路由库。你只需要在app目录下创建文件夹和文件,Next.js就会自动帮你搞定路由。

类比理解:

文件系统路由就像酒店的房间号系统

  • app/page.tsx → 大厅(首页 /
  • app/about/page.tsx/about 房间
  • app/blog/page.tsx/blog 房间
  • app/blog/[slug]/page.tsx/blog/xxx 动态房间(每个客人不同)

关键规则:

  • 每个page.tsx文件代表一个页面
  • 文件夹名就是URL路径段
  • [参数名]表示动态路由参数

页面和路由实战

typescript
加载中...

布局(Layout):页面的共享外壳

每个网站都有一些所有页面共享的部分——比如导航栏、页脚、侧边栏。在Next.js中,这些共享部分叫做布局(Layout)

类比理解:

布局就像相框

  • 相框的边框是固定的(导航栏、页脚)
  • 相框里的照片可以换(页面内容)
  • 你不需要每次都重新做相框

布局的特点:

  • 在页面切换时不会重新渲染(保持状态)
  • 可以嵌套(子页面有自己的布局)
  • 是定义<html><body>标签的地方

布局实战

typescript
加载中...

服务器组件 vs 客户端组件:一个关键区别

这是Next.js 13+最重要的概念之一,也是很多人容易混淆的地方。

问题场景:

你写了一个页面,想在点击按钮时显示一个计数器。但页面报错了,提示你不能在服务器组件中使用useState

为什么?

因为Next.js默认把所有组件当作服务器组件——它们在服务器上运行,不在用户的浏览器里。服务器组件不能做"交互"的事情(比如响应点击、管理状态)。

类比理解:

| 组件类型 | 类比 | 能做什么 | |----------|------|----------| | 服务器组件 | 厨房里的厨师 | 获取数据、渲染HTML、访问数据库 | | 客户端组件 | 餐厅里的服务员 | 响应用户操作、管理状态、使用浏览器API |

关键规则:

  • 服务器组件:默认,可以直接await获取数据
  • 客户端组件:需要在文件顶部添加"use client"指令
  • 服务器组件不能使用useState、useEffect等Hook
  • 客户端组件不能直接访问数据库

两种组件对比

typescript
加载中...

常见错误

常见错误

错误1:在服务器组件中使用useState

// 错误!服务器组件不能用 useState
export default function Page() {
  const [count, setCount] = useState(0); // 报错!
  return <div>{count}</div>;
}

解决: 在文件顶部添加 "use client",或者把交互部分抽成客户端组件。

错误2:忘记page.tsx文件名

// 错误!app/about.tsx 不会创建 /about 路由
// 正确:app/about/page.tsx

解决: 每个路由目录下必须有 page.tsx 文件。

错误3:动态路由参数类型错误

// 错误!params 是对象,不是字符串
export default function Page({ params }: { params: string }) {}

// 正确
export default function Page({ params }: { params: { slug: string } }) {}

解决: 动态路由的params是一个对象,key是参数名。

错误4:在客户端组件中直接访问数据库

"use client";
import { db } from "@/lib/database"; // 客户端不能用这个!

// 解决:把数据获取放在服务器组件,通过props传递

动手实践

现在轮到你了!让我们动手练习:

练习1:创建一个用户个人资料页面

  • 路径:/users/[userId]
  • 显示用户ID
  • 添加一个"返回首页"的链接

练习2:创建一个嵌套布局

  • /dashboard目录下创建布局
  • 布局包含侧边栏和内容区
  • 创建两个子页面:/dashboard/settings/dashboard/profile

练习3:区分服务器组件和客户端组件

  • 创建一个服务器组件,显示当前时间(服务器时间)
  • 创建一个客户端组件,显示一个计数器
  • 思考:为什么"当前时间"适合用服务器组件?

提示:

  • 服务器组件适合展示静态或服务器端数据
  • 客户端组件适合需要用户交互的场景
  • 可以在服务器组件中嵌套客户端组件

本章总结

恭喜你完成了Next.js基础的学习!让我们回顾一下:

本章学到的:

  1. Next.js是基于React的全栈框架,"前厅后厨一体化"
  2. 文件系统路由:文件路径即URL,不需要手动配置路由
  3. 布局(Layout):页面的"共享外壳",导航栏和页脚放在这里
  4. 服务器组件 vs 客户端组件:默认是服务器组件,交互需要"use client"

前后对比:

| 方面 | 之前(纯React) | 现在(Next.js) | |------|-----------------|-----------------| | 路由 | 需要react-router配置 | 文件路径即路由 | | 数据获取 | useEffect + fetch | 直接在组件中await | | SEO | 需要额外配置 | 开箱即用 | | 前后端 | 需要两个项目 | 一个项目搞定 |

下一章预告:

我们已经有了页面,但博客还需要后端API来管理文章数据。下一章我们将学习Next.js的API路由——如何在同一个项目中创建RESTful API,让前端和后端共享TypeScript类型。

交互式练习

1 / 1

创建Next.js页面

创建一个用户个人资料页面,接收userId参数

typescript
Loading...

章节测验

问题 1 / 3得分: 0 / 3

Next.js默认使用什么类型的组件?

A
客户端组件
B
服务器组件
C
静态组件
D
动态组件