Next.js 15 App Router 完全指南
全面了解 Next.js 15 的 App Router,包括路由、数据获取、缓存策略等核心概念。
4 天前
5 分钟阅读
370 次浏览
Next.js 15 App Router 完全指南
Next.js 15 的 App Router 带来了全新的应用架构和更强大的功能。让我们深入了解如何充分利用它。
目录结构
text
app/
├── page.tsx # 首页 /
├── layout.tsx # 根布局
├── loading.tsx # 加载状态
├── error.tsx # 错误处理
├── blog/
│ ├── page.tsx # /blog
│ ├── [slug]/
│ │ └── page.tsx # /blog/[slug]
│ └── layout.tsx # 博客布局
└── api/
└── posts/
└── route.ts # API 路由Server Components(默认)
tsx
// app/blog/page.tsx
async function BlogPage() {
// 直接在组件中获取数据
const posts = await db.post.findMany();
return (
<div>
{posts.map(post => (
<PostCard key={post.id} post={post} />
))}
</div>
);
}
export default BlogPage;数据获取策略
1. 静态生成(推荐)
tsx
// 构建时生成
export const dynamic = 'force-static';
async function StaticPage() {
const data = await fetch('https://api.example.com/data');
return <div>{/* ... */}</div>;
}2. 动态渲染
tsx
// 每次请求时生成
export const dynamic = 'force-dynamic';
async function DynamicPage() {
const data = await fetch('https://api.example.com/data', {
cache: 'no-store'
});
return <div>{/* ... */}</div>;
}3. 增量静态再生成(ISR)
tsx
// 每 60 秒重新验证
async function ISRPage() {
const data = await fetch('https://api.example.com/data', {
next: { revalidate: 60 }
});
return <div>{/* ... */}</div>;
}并行数据获取
tsx
async function ParallelDataPage() {
// 并行获取多个数据源
const [posts, users, comments] = await Promise.all([
fetchPosts(),
fetchUsers(),
fetchComments(),
]);
return (
<div>
<Posts data={posts} />
<Users data={users} />
<Comments data={comments} />
</div>
);
}流式渲染与 Suspense
tsx
import { Suspense } from 'react';
async function Posts() {
const posts = await fetchPosts(); // 慢速数据
return <PostList posts={posts} />;
}
function Page() {
return (
<div>
<Header /> {/* 立即显示 */}
<Suspense fallback={<LoadingPosts />}>
<Posts /> {/* 异步加载 */}
</Suspense>
</div>
);
}路由处理
动态路由
tsx
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map(post => ({ slug: post.slug }));
}
async function BlogPost({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return <article>{post.content}</article>;
}路由组
text
app/
├── (marketing)/
│ ├── page.tsx # /
│ └── about/
│ └── page.tsx # /about
└── (shop)/
├── products/
└── cart/Metadata API
tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'My Blog',
description: 'A blog about web development',
openGraph: {
title: 'My Blog',
description: 'A blog about web development',
images: ['/og-image.jpg'],
},
};
// 动态 metadata
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
};
}API Routes
tsx
// app/api/posts/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const posts = await db.post.findMany();
return NextResponse.json(posts);
}
export async function POST(request: NextRequest) {
const body = await request.json();
const post = await db.post.create({ data: body });
return NextResponse.json(post, { status: 201 });
}缓存策略
Next.js 15 提供了多层缓存:
- Request Memoization:同一请求中的相同 fetch 自动去重
- Data Cache:跨请求的持久化缓存
- Full Route Cache:静态路由的完整缓存
- Router Cache:客户端导航缓存
性能优化技巧
1. 使用 loading.tsx
tsx
// app/blog/loading.tsx
export default function Loading() {
return <BlogSkeleton />;
}2. 图片优化
tsx
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero"
width={800}
height={600}
priority // 首屏图片
/>3. 字体优化
tsx
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
);
}总结
Next.js 15 的 App Router 提供了:
- 更好的性能(Server Components)
- 更灵活的数据获取
- 内置的流式渲染
- 强大的缓存控制
- 更好的开发体验
标签:Next.js, React, Performance
周温
全栈开发工程师,专注于前端技术栈和物联网应用开发。拥有丰富的 React、Next.js、Nest.js 项目经验,擅长构建高性能、可扩展的 Web 应用。