Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

目录

  1. Next.js 简介
  2. 环境准备
  3. 创建第一个 Next.js 应用
  4. 项目结构解析
  5. 页面和路由
  6. 样式处理
  7. 数据获取
  8. 部署应用

1. Next.js 简介

Next.js 是一个基于 React 的开源 Web 开发框架,由 Vercel 公司开发和维护。它提供了许多开箱即用的功能,使得构建现代化的 React 应用变得更加简单高效。

Next.js 的主要特性:

  • 服务端渲染(SSR): 提升首屏加载速度和SEO友好性
  • 静态站点生成(SSG): 构建高性能的静态网站
  • 增量静态再生(ISR): 结合SSR和SSG的优势
  • 自动代码分割: 减少初始加载时间
  • 内置CSS支持: 支持多种样式方案
  • API路由: 轻松创建后端API接口
  • 图像优化: 自动优化图片性能
  • 快速刷新: 开发时的即时反馈

2. 环境准备

在开始之前,确保你的开发环境满足以下要求:

Node.js 安装

Next.js 需要 Node.js 12.22.0 或更高版本。你可以通过以下命令检查是否已安装:

1
2
node -v
npm -v

如果没有安装 Node.js,可以从 Node.js官网 下载并安装。

代码编辑器推荐

  • Visual Studio Code (推荐)
  • WebStorm
  • Atom

3. 创建第一个 Next.js 应用

使用 create-next-app 工具快速创建一个新的 Next.js 项目:

1
2
3
4
5
6
7
8
# 使用 npx 创建项目
npx create-next-app@latest my-next-app

# 或者使用 yarn
yarn create next-app my-next-app

# 或者使用 pnpm
pnpm create next-app my-next-app

创建过程中会提示你选择一些选项:

  • 是否使用 TypeScript
  • 是否使用 ESLint
  • 是否使用 Tailwind CSS
  • 是否使用 src/ 目录
  • 是否使用 App Router (推荐)
  • 是否自定义导入别名

选择完成后,进入项目目录并启动开发服务器:

1
2
cd my-next-app
npm run dev

打开浏览器访问 http://localhost:3000,你将看到 Next.js 的欢迎页面。


4. 项目结构解析

Next.js 项目的基本结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my-next-app/
├── node_modules/
├── public/
│ ├── favicon.ico
│ └── next.svg
├── src/
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── globals.css
│ └── components/
├── .eslintrc.json
├── .gitignore
├── next.config.js
├── package.json
├── README.md
└── tsconfig.json

关键目录说明:

  • public/: 存放静态资源文件,如图片、图标等
  • src/app/: 应用的主要代码目录(使用App Router)
  • src/components/: 可复用的React组件
  • next.config.js: Next.js 配置文件
  • package.json: 项目依赖和脚本配置

5. 页面和路由

Next.js 使用基于文件系统的路由机制。在 src/app/ 目录下创建文件即可自动生成对应路由。

基本页面创建

创建一个简单的页面,在 src/app/ 目录下新建 about/page.tsx

1
2
3
4
5
6
7
8
9
// src/app/about/page.tsx
export default function About() {
return (
<div>
<h1>关于我们</h1>
<p>这是关于我们的页面</p>
</div>
);
}

访问 http://localhost:3000/about 即可看到这个页面。

动态路由

创建动态路由页面,例如用户详情页,在 src/app/ 目录下新建 users/[id]/page.tsx

1
2
3
4
5
6
7
8
9
// src/app/users/[id]/page.tsx
export default function UserDetail({ params }: { params: { id: string } }) {
return (
<div>
<h1>用户详情</h1>
<p>用户ID: {params.id}</p>
</div>
);
}

访问 http://localhost:3000/users/123 可以看到参数被正确传递。

嵌套路由

创建嵌套路由,在 src/app/dashboard/ 目录下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div>
<h2>仪表板布局</h2>
<nav>
<ul>
<li><a href="/dashboard/profile">个人资料</a></li>
<li><a href="/dashboard/settings">设置</a></li>
</ul>
</nav>
<main>{children}</main>
</div>
);
}
1
2
3
4
// src/app/dashboard/page.tsx
export default function Dashboard() {
return <h1>仪表板主页</h1>;
}
1
2
3
4
// src/app/dashboard/profile/page.tsx
export default function Profile() {
return <h1>个人资料页面</h1>;
}

6. 样式处理

Next.js 支持多种样式方案:

全局样式

src/app/globals.css 中添加全局样式:

1
2
3
4
5
6
7
8
9
10
11
12
/* src/app/globals.css */
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto;
}

.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}

在根布局中引入全局样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/app/layout.tsx
import './globals.css';
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: '我的 Next.js 应用',
description: '使用 Next.js 构建的现代 Web 应用',
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="zh-CN">
<body>{children}</body>
</html>
);
}

CSS Modules

创建组件级样式文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
/* src/components/Button.module.css */
.button {
background-color: #0070f3;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}

.button:hover {
background-color: #0051a2;
}

在组件中使用:

1
2
3
4
5
6
7
8
9
10
// src/components/Button.tsx
import styles from './Button.module.css';

export default function Button({ children }: { children: React.ReactNode }) {
return (
<button className={styles.button}>
{children}
</button>
);
}

Tailwind CSS

如果在创建项目时选择了 Tailwind CSS,可以直接使用:

1
2
3
4
5
6
7
8
9
10
export default function HomePage() {
return (
<div className="min-h-screen bg-gray-100 flex items-center justify-center">
<div className="bg-white p-8 rounded-lg shadow-md">
<h1 className="text-3xl font-bold text-gray-800 mb-4">欢迎来到 Next.js</h1>
<p className="text-gray-600">这是一个使用 Tailwind CSS 样式的示例</p>
</div>
</div>
);
}

7. 数据获取

Next.js 提供了多种数据获取方式:

服务端获取数据 (SSR)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/app/posts/page.tsx
async function getPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
return res.json();
}

export default async function PostsPage() {
const posts = await getPosts();

return (
<div>
<h1>文章列表</h1>
<ul>
{posts.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}

客户端获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// src/app/client-posts/page.tsx
'use client';

import { useEffect, useState } from 'react';

export default function ClientPostsPage() {
const [posts, setPosts] = useState<any[]>([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => {
setPosts(data);
setLoading(false);
});
}, []);

if (loading) return <div>加载中...</div>;

return (
<div>
<h1>客户端获取的文章列表</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}

静态生成数据 (SSG)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// src/app/static-posts/page.tsx
async function getStaticPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
return res.json();
}

export default async function StaticPostsPage() {
const posts = await getStaticPosts();

return (
<div>
<h1>静态生成的文章列表</h1>
<ul>
{posts.slice(0, 5).map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}

// 预渲染静态参数
export async function generateStaticParams() {
const posts = await getStaticPosts();
return posts.slice(0, 5).map((post: any) => ({
id: post.id.toString(),
}));
}

8. 部署应用

Next.js 应用可以部署到多个平台:

部署到 Vercel (推荐)

Vercel 是 Next.js 的官方托管平台,提供一键部署功能:

  1. 将代码推送到 GitHub/GitLab/Bitbucket
  2. 登录 Vercel
  3. 点击 “New Project”
  4. 选择你的代码仓库
  5. 点击 “Deploy”

构建和导出静态文件

1
2
3
4
5
# 构建生产版本
npm run build

# 导出静态文件
npm run export

部署到其他平台

构建生产版本:

1
npm run build

然后将 .next 目录中的内容部署到你的服务器。


总结

通过本教程,你已经学会了:

  1. Next.js 的基本概念和优势
  2. 如何创建和运行 Next.js 项目
  3. 页面和路由系统的工作原理
  4. 不同样式方案的使用方法
  5. 数据获取的不同方式
  6. 应用部署的基本流程

在接下来的教程中,我们将深入探讨 Next.js 的高级特性,包括 API 路由、中间件、性能优化等内容。

评论