Next.js 详细教程

Next.js 是一个基于 React 的框架,用于构建服务端渲染(SSR)和静态生成(SSG)的应用程序。它提供了许多开箱即用的功能,如路由、API 路由、图像优化等,让开发者能够快速构建高性能的 React 应用。

目录

  1. Next.js 简介
  2. 环境准备
  3. 创建第一个 Next.js 项目
  4. 项目结构
  5. 页面和路由
  6. 数据获取
  7. API 路由
  8. 样式处理
  9. 静态文件服务
  10. 部署
  11. 高级特性

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 (推荐)

  1. 将代码推送到 GitHub、GitLab 或 Bitbucket
  2. 在 Vercel 上导入项目
  3. Vercel 会自动检测 Next.js 项目并进行优化部署

其他平台

Next.js 也可以部署到 Node.js 服务器、静态文件服务器或其他云平台:

  1. 构建项目:npm run build
  2. 启动生产服务器: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:

  1. 创建 tsconfig.json 文件
  2. 安装依赖:npm install --save-dev typescript @types/react @types/node
  3. 重启开发服务器

中间件

在 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 官方文档









results matching ""

    No results matching ""