适用人群:有React基础
难度:中等
预计学习时间:30-40小时
为什么学 Next.js?
| 优势 | 说明 |
|---|
| React全栈 | 前后端一体化,开发效率极高 |
| SSR/SSG | 服务端渲染,SEO友好 |
| 生态最强 | Vercel维护,社区最活跃 |
| 部署简单 | Vercel一键部署 |
| 企业采用 | Netflix/TikTok/Notion都在用 |
学习路线
第1阶段:基础(1周)
├── 项目创建与结构
├── App Router(新路由系统)
├── 页面与布局(page.tsx/layout.tsx)
├── 客户端与服务端组件
└── 样式方案(CSS Modules/Tailwind)
第2阶段:数据获取(2周)
├── Server Components数据获取
├── Server Actions(表单处理)
├── API Routes
├── 数据库(Prisma + PostgreSQL)
└── 缓存策略(revalidate)
第3阶段:认证与中间件(1周)
├── NextAuth.js
├── Session管理
├── 中间件(middleware.ts)
└── 权限控制
第4阶段:高级特性(2周)
├── 图片优化(next/image)
├── 字体优化(next/font)
├── 国际化(i18n)
├── SEO优化(metadata)
├── 性能优化
└── 测试(Jest/Playwright)
核心代码示例
// app/layout.tsx - 根布局
export const metadata = {
title: 'My App',
description: 'Built with Next.js',
}
export default function RootLayout({ children }) {
return (
<html lang="zh-CN">
<body>{children}</body>
</html>
)
}
// app/page.tsx - 首页(服务端组件)
async function getPosts() {
const res = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 } // 每60秒重新验证
})
return res.json()
}
export default async function HomePage() {
const posts = await getPosts()
return (
<main>
<h1>Latest Posts</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.summary}</p>
</article>
))}
</main>
)
}
// app/posts/[id]/page.tsx - 动态路由
export async function generateStaticParams() {
const posts = await getPosts()
return posts.map(post => ({ id: post.id }))
}
export default async function PostPage({ params }) {
const post = await getPost(params.id)
return <article>{post.content}</article>
}
// app/components/Counter.tsx - 客户端组件
'use client'
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
)
}
// app/api/posts/route.ts - API路由
import { NextResponse } from 'next/server'
export async function GET() {
const posts = await db.post.findMany()
return NextResponse.json(posts)
}
export async function POST(request) {
const body = await request.json()
const post = await db.post.create({ data: body })
return NextResponse.json(post, { status: 201 })
}
// Server Actions - 表单处理
// app/actions.ts
'use server'
export async function createPost(formData) {
const title = formData.get('title')
const content = formData.get('content')
await db.post.create({
data: { title, content }
})
revalidatePath('/posts')
}
// app/posts/new/page.tsx
import { createPost } from '../actions'
export default function NewPost() {
return (
<form action={createPost}>
<input name="title" placeholder="标题" />
<textarea name="content" placeholder="内容" />
<button type="submit">发布</button>
</form>
)
}
// Prisma ORM
// prisma/schema.prisma
// generator client {
// provider = "prisma-client-js"
// }
//
// datasource db {
// provider = "postgresql"
// url = env("DATABASE_URL")
// }
//
// model Post {
// id String @id @default(cuid())
// title String
// content String?
// createdAt DateTime @default(now())
// }
部署方案
| 方案 | 说明 | 费用 |
|---|
| Vercel | 官方推荐,一键部署 | 免费/付费 |
| Docker | 自建服务器部署 | 服务器费用 |
| AWS Amplify | AWS生态 | 按量付费 |
| Netlify | Vercel替代 | 免费/付费 |
推荐资源
| 资源 | 说明 |
|---|
| Next.js官方文档 | 最好的学习资料 |
| Next.js Learn | 官方互动教程 |
| Vercel Blog | 最佳实践和新特性 |
| Prisma文档 | 数据库ORM |