Next.js 详细教程
Next.js 是一个基于 React 的框架,用于构建服务端渲染(SSR)和静态生成(SSG)的应用程序。它提供了许多开箱即用的功能,如路由、API 路由、图像优化等,让开发者能够快速构建高性能的 React 应用。
目录
- Next.js 简介
- 环境准备
- 创建第一个 Next.js 项目
- 项目结构
- 页面和路由
- 数据获取
- API 路由
- 样式处理
- 静态文件服务
- 部署
- 高级特性
Next.js 简介
Next.js 的主要特点:
- 混合渲染:支持服务端渲染(SSR)、静态生成(SSG)和客户端渲染(CSR)
- 文件系统路由:基于文件系统自动创建路由
- API 路由:无需额外配置即可创建 API 端点
- 内置 CSS 和 Sass 支持:支持 CSS 模块和 Sass
- 图像优化:自动优化图像
- 国际化路由:内置国际化支持
- 快速刷新:开发时保持状态的快速刷新
- TypeScript 支持:内置 TypeScript 支持
环境准备
在开始之前,确保你的系统安装了:
- Node.js 12.22.0 或更高版本
- npm 或 yarn
创建第一个 Next.js 项目
使用以下命令创建一个新的 Next.js 项目:
npx create-next-app@latest my-next-app
# 或
yarn create next-app my-next-app
创建过程中会询问一些配置选项,你可以根据需要选择 TypeScript、ESLint 等。
进入项目目录并启动开发服务器:
cd my-next-app
npm run dev
# 或
yarn dev
开发服务器通常运行在 http://localhost:3000
。
项目结构
一个典型的 Next.js 项目结构如下:
my-next-app/
├── .next/ # 构建输出目录
├── node_modules/ # 依赖项
├── pages/ # 页面目录
│ ├── api/ # API 路由
│ ├── _app.js # 自定义 App 组件
│ ├── _document.js # 自定义 Document 组件
│ └── index.js # 首页
├── public/ # 静态文件目录
├── styles/ # 全局样式目录
├── .gitignore
├── package.json
└── README.md
页面和路由
Next.js 使用文件系统作为路由系统。pages
目录中的每个文件都会自动成为一个路由。
基本路由
pages/index.js
→/
pages/about.js
→/about
pages/blog/first-post.js
→/blog/first-post
动态路由
使用方括号 []
创建动态路由:
pages/blog/[slug].js
→/blog/:slug
(如/blog/hello-world
)pages/[username]/settings.js
→/:username/settings
(如/john/settings
)pages/post/[...all].js
→/post/*
(如/post/2020/id/title
)
页面间导航
使用 next/link
进行客户端导航:
jsx
import Link from 'next/link'
export default function Home() {
return (
<div>
<h1>Home Page</h1>
<Link href="/about">
<a>About Us</a>
</Link>
</div>
)
}
自定义 App 和 Document
_app.js
是 Next.js 初始化页面的顶层组件,可以用于:
- 保持页面间的状态
- 注入全局样式
- 添加全局布局
jsx
import '../styles/globals.css'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
_document.js
用于自定义文档结构,通常用于设置 <html>
和 <body>
标签:
jsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
数据获取
Next.js 提供了多种数据获取方法:
getStaticProps (静态生成)
在构建时获取数据并预渲染页面:
jsx
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return {
props: {
data
}
}
}
export default function Page({ data }) {
// 渲染数据...
}
getStaticPaths (动态路由的静态生成)
为动态路由指定要预渲染的路径:
jsx
export async function getStaticPaths() {
const res = await fetch('https://api.example.com/posts')
const posts = await res.json()
const paths = posts.map(post => ({
params: { id: post.id }
}))
return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`)
const post = await res.json()
return { props: { post } }
}
export default function Post({ post }) {
// 渲染文章...
}
getServerSideProps (服务端渲染)
在每个请求时获取数据:
jsx
export async function getServerSideProps(context) {
const { req, res, query } = context
const response = await fetch('https://api.example.com/data')
const data = await response.json()
return {
props: {
data
}
}
}
export default function Page({ data }) {
// 渲染数据...
}
API 路由
Next.js 允许你在 pages/api
目录下创建 API 端点:
js
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
然后可以通过 /api/hello
访问这个 API。
样式处理
Next.js 支持多种样式解决方案:
全局 CSS
在 _app.js
中导入全局 CSS 文件:
js
import '../styles/globals.css'
CSS 模块
创建以 .module.css
结尾的文件:
/* styles/Button.module.css */
.error {
color: white;
background-color: red;
}
然后在组件中使用:
jsx
import styles from './Button.module.css'
export function Button() {
return <button className={styles.error}>Click Me</button>
}
Sass 支持
安装 Sass:
npm install sass
然后创建 .scss
或 .sass
文件:
jsx
import styles from './Button.module.scss'
CSS-in-JS
Next.js 也支持 styled-jsx 和其他 CSS-in-JS 库:
jsx
export default function Home() {
return (
<div>
<style jsx>{`
h1 {
color: red;
}
`}</style>
<h1>Hello World</h1>
</div>
)
}
静态文件服务
将静态文件(如图像)放在 public
目录中,然后可以直接引用:
jsx
<img src="/logo.png" alt="Logo" />
部署
Next.js 应用可以部署到多种平台:
Vercel (推荐)
- 将代码推送到 GitHub、GitLab 或 Bitbucket
- 在 Vercel 上导入项目
- Vercel 会自动检测 Next.js 项目并进行优化部署
其他平台
Next.js 也可以部署到 Node.js 服务器、静态文件服务器或其他云平台:
- 构建项目:
npm run build
- 启动生产服务器:
npm run start
高级特性
图像优化
使用 next/image
组件优化图像:
jsx
import Image from 'next/image'
export default function Home() {
return (
<Image
src="/profile.jpg"
alt="Profile Picture"
width={500}
height={500}
/>
)
}
国际化路由
Next.js 内置了国际化路由支持:
js
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
}
环境变量
创建 .env.local
文件:
NEXT_PUBLIC_API_URL=https://api.example.com
然后可以在代码中访问:
js
const apiUrl = process.env.NEXT_PUBLIC_API_URL
TypeScript 支持
Next.js 内置 TypeScript 支持。要添加 TypeScript:
- 创建
tsconfig.json
文件 - 安装依赖:
npm install --save-dev typescript @types/react @types/node
- 重启开发服务器
中间件
在 Next.js 12+ 中,你可以使用中间件在请求完成前运行代码:
js
// middleware.js
import { NextResponse } from 'next/server'
export function middleware(req) {
if (req.nextUrl.pathname.startsWith('/about')) {
return NextResponse.redirect(new URL('/', req.url))
}
}
总结
Next.js 是一个功能强大的 React 框架,提供了服务端渲染、静态生成、API 路由等开箱即用的功能。通过本教程,你应该已经掌握了 Next.js 的基本概念和常用功能。要了解更多,可以参考 Next.js 官方文档。