跳到主要内容

3.2 现代开发框架

为什么需要框架?

想象一下你要做一顿饭。

方式一:从零开始。 你去菜市场买菜、洗菜、切菜、调料、掌握火候……每一环节都自己来。做一顿饭可能要两小时,而且味道好不好全靠经验。

方式二:用预制菜/料理包。 食材洗好切好了,调料配好了,你只需要下锅炒几分钟。速度快,味道稳定,虽然灵活性差一点,但对大多数人来说足够好了。

框架就是编程世界的"料理包"。

理论上你可以用纯 HTML、CSS、JavaScript 手搓一个网站出来。但你会发现——写到第三页就开始崩溃了。每个页面都重复一堆导航栏代码,改个颜色要在十个文件里改,页面切换的时候整页刷新白屏闪一下……

框架帮你把这些"重复、通用、烦人"的事情都封装好了。路由、状态管理、样式方案、构建打包、性能优化……开箱即用。

为什么 AI 编程时代框架更关键? 因为 AI 对流行框架的理解最深、生成的代码质量最高。你让 AI 写一个 Next.js 的页面,它大概率写得又快又好;你让它写一个冷门框架的代码,它可能一本正经地胡说八道。选主流框架 = 让 AI 发挥最大能力。


Next.js:全栈开发的瑞士军刀

什么是 Next.js?

Next.js 是目前最推荐的 Web 开发框架,没有之一。它是基于 React 构建的,但比 React 多了一大堆"开箱即用"的能力。

为什么选它? 四个理由:

  1. 全栈框架 —— 前端页面和后端 API 在同一个项目里,不用维护两套代码。就像你不需要单独租一个厨房了,Next.js 给你的是一个"前厅带厨房"的商铺。
  2. Vercel 生态 —— Next.js 背后的公司 Vercel 有最好用的部署平台。代码推到 GitHub,自动部署上线,免费额度对个人项目绰绰有余。
  3. AI 友好 —— 目前 AI 编程工具(Cursor、Claude Code 等)对 Next.js 的支持最好,生成的代码能直接跑。
  4. 性能优秀 —— 自动代码分割、图片优化、服务端渲染,不用你手动优化。

创建项目

打开终端,一行命令搞定:

npx create-next-app@latest my-app

它会问你几个问题:

✔ Would you like to use TypeScript? → Yes(用 TypeScript,类型安全)
✔ Would you like to use ESLint? → Yes(代码检查,帮你少犯错)
✔ Would you like to use Tailwind CSS? → Yes(必须选!下面会讲)
✔ Would you like your code inside a `src/` directory? → Yes(代码放 src 下更整洁)
✔ Would you like to use App Router? → Yes(新版路由系统,必选)
✔ Would you like to use Turbopack for next dev? → Yes(更快的开发服务器)
✔ Would you like to customize the import alias? → No(默认 @/ 就行)

为什么要这样选? TypeScript 让 AI 更容易理解你的代码;Tailwind CSS 是目前最好的样式方案;App Router 是 Next.js 13+ 推荐的新架构,性能更好。

项目结构完全解读

创建完成后,你会看到这样的目录结构:

my-app/
├── public/ # 静态资源(图片、字体等)
│ ├── next.svg # Next.js logo
│ └── vercel.svg # Vercel logo
├── src/
│ └── app/ # 核心目录!所有页面都在这里
│ ├── favicon.ico # 网站图标
│ ├── globals.css # 全局样式
│ ├── layout.tsx # 根布局(所有页面共用的外壳)
│ └── page.tsx # 首页(访问 / 时显示)
├── next.config.ts # Next.js 配置文件
├── package.json # 项目依赖和脚本
├── tsconfig.json # TypeScript 配置
├── tailwind.config.ts # Tailwind CSS 配置
└── postcss.config.mjs # PostCSS 配置(Tailwind 底层依赖)

重点理解 src/app/ 目录:这是你写代码的核心战场。每个文件夹代表一个路由(网址),每个文件名有特殊含义:

文件名作用必须?
page.tsx这个路由显示的页面内容
layout.tsx包裹子页面的布局外壳(导航栏、侧边栏等)可选
loading.tsx页面加载时显示的 loading 状态可选
error.tsx页面出错时显示的错误页面可选
not-found.tsx404 页面可选

页面和路由(文件即路由)

Next.js 最酷的设计之一:文件路径就是网址路径。你不需要手动配置路由表,创建文件就行。

src/app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── blog/
│ ├── page.tsx → /blog(文章列表)
│ └── [slug]/
│ └── page.tsx → /blog/my-first-post(动态路由)
├── dashboard/
│ ├── layout.tsx → 仪表盘的共同布局
│ ├── page.tsx → /dashboard
│ └── settings/
│ └── page.tsx → /dashboard/settings
└── api/
└── hello/
└── route.ts → GET /api/hello

方括号 [slug] 是动态路由,意思是这个位置可以是任何值。比如 /blog/hello-world/blog/nextjs-tutorial 都会匹配 blog/[slug]/page.tsx

来看一个实际的页面代码:

// src/app/about/page.tsx
// 这就是一个普通的 React 组件,Next.js 自动把它变成一个页面

export default function AboutPage() {
return (
<div>
<h1>关于我们</h1>
<p>这是一个用 Next.js 搭建的网站。</p>
</div>
)
}
// src/app/layout.tsx — 根布局,所有页面都被它包裹
import type { Metadata } from "next";
import "./globals.css";

export const metadata: Metadata = {
title: "我的网站",
description: "用 Next.js + Tailwind 打造",
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="zh-CN">
<body className="bg-gray-50 text-gray-900 antialiased">
<nav className="p-4 bg-white shadow">
<a href="/" className="mr-4">首页</a>
<a href="/about" className="mr-4">关于</a>
<a href="/blog">博客</a>
</nav>
<main className="max-w-4xl mx-auto p-6">
{children}
</main>
</body>
</html>
);
}

children 就是当前页面的 page.tsx 渲染的内容。所有页面都会自动套上这个布局(导航栏 + main 容器)。

Server Components vs Client Components

Next.js App Router 引入了一个重要概念:默认所有组件都是 Server Components(服务端组件)

Server Components(服务端组件):

  • 在服务器上渲染,HTML 直接发给浏览器
  • 可以直接访问数据库、读文件、调用 API
  • 不能用 useStateuseEffect、事件监听(onClick 等)
  • 适合:展示数据、获取内容、不需要交互的页面

Client Components(客户端组件):

  • 在浏览器里渲染,可以交互
  • 需要在文件顶部加 "use client" 声明
  • 可以用 useStateuseEffect、事件监听
  • 适合:表单、按钮点击、实时更新、动画

怎么选择? 简单原则:默认用 Server Component,需要交互时才加 "use client"

// ✅ Server Component — 展示文章内容,不需要交互
// src/app/blog/[slug]/page.tsx
export default async function BlogPost({ params }: { params: { slug: string } }) {
const res = await fetch(`https://api.example.com/posts/${params.slug}`);
const post = await res.json();

return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}
// ✅ Client Component — 有按钮点击交互
// src/components/LikeButton.tsx
"use client";

import { useState } from "react";

export default function LikeButton() {
const [likes, setLikes] = useState(0);

return (
<button
onClick={() => setLikes(likes + 1)}
className="bg-pink-500 text-white px-4 py-2 rounded-lg hover:bg-pink-600"
>
❤️ 点赞 ({likes})
</button>
);
}

然后在 Server Component 里直接引入 Client Component:

// src/app/blog/[slug]/page.tsx
import LikeButton from "@/components/LikeButton";

export default async function BlogPost({ params }: { params: { slug: string } }) {
// ... 获取数据
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
<LikeButton /> {/* 交互部分单独抽成 Client Component */}
</article>
);
}

API Routes(后端接口)

Next.js 的 API 路由让你在同一个项目里写后端逻辑,不需要单独搭后端服务器。

// src/app/api/hello/route.ts
import { NextResponse } from "next/server";

// GET 请求处理
export async function GET() {
return NextResponse.json({ message: "你好,世界!" });
}

// POST 请求处理
export async function POST(request: Request) {
const body = await request.json();
return NextResponse.json({
message: `收到你的数据:${body.name}`,
});
}

访问 http://localhost:3000/api/hello 就能拿到 { "message": "你好,世界!" }

你可以在前端直接调用:

const res = await fetch("/api/hello");
const data = await res.json();
// data.message === "你好,世界!"

数据获取(Server Components 中直接 fetch)

在 Server Components 里,你可以直接 await fetch(),非常直觉:

// src/app/blog/page.tsx
interface Post {
id: number;
title: string;
excerpt: string;
}

export default async function BlogPage() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts?_limit=10");
const posts: Post[] = await res.json();

return (
<div>
<h1 className="text-3xl font-bold mb-6">博客文章</h1>
<div className="space-y-4">
{posts.map((post) => (
<a
key={post.id}
href={`/blog/${post.id}`}
className="block p-4 bg-white rounded-lg shadow hover:shadow-md transition-shadow"
>
<h2 className="text-xl font-semibold">{post.title}</h2>
<p className="text-gray-500 mt-1">{post.excerpt}</p>
</a>
))}
</div>
</div>
);
}

不需要 useEffect,不需要 useState,不需要 loading 状态——因为数据在服务器上就获取好了,浏览器收到的直接是渲染好的 HTML。

完整实战:一个博客系统

让我们把上面的知识串起来,做一个完整的博客。

// src/app/blog/[slug]/page.tsx — 动态博客文章页

interface Post {
id: number;
title: string;
body: string;
}

export default async function BlogPost({
params,
}: {
params: { slug: string };
}) {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${params.slug}`
);
const post: Post = await res.json();

return (
<article className="max-w-2xl mx-auto py-8">
<h1 className="text-4xl font-bold mb-4">{post.title}</h1>
<div className="prose prose-lg">
<p>{post.body}</p>
</div>
<div className="mt-8 pt-4 border-t">
<a href="/blog" className="text-blue-500 hover:underline">
← 返回文章列表
</a>
</div>
</article>
);
}
// src/app/blog/[slug]/not-found.tsx — 文章不存在时显示

export default function NotFound() {
return (
<div className="text-center py-20">
<h1 className="text-6xl font-bold text-gray-300">404</h1>
<p className="text-xl text-gray-500 mt-4">这篇文章不存在</p>
<a href="/blog" className="text-blue-500 hover:underline mt-4 block">
回到博客首页
</a>
</div>
);
}

访问 /blog/1 就能看到文章内容,访问 /blog/99999 会显示 404。整个过程零 JavaScript 发送到浏览器(Server Component),SEO 友好,加载飞快。


Tailwind CSS:写样式的新方式

什么是 Tailwind?

传统写 CSS 是这样的:你先给按钮起个类名 class="submit-btn",然后在 CSS 文件里写:

.submit-btn {
background: #3b82f6;
color: white;
padding: 8px 20px;
border-radius: 8px;
font-weight: bold;
}

一个项目写下来,CSS 文件几百行,各种类名互相覆盖,改一个地方可能炸另一个地方。

Tailwind 换了一种思路——直接在 HTML 里用"工具类"

<button class="bg-blue-500 text-white px-5 py-2 rounded-lg font-bold">
提交
</button>

看到没?bg-blue-500 是蓝色背景,text-white 是白色文字,px-5 py-2 是内边距,rounded-lg 是圆角。每个类只做一件小事,组合起来就是完整的样式。

为什么大家都爱 Tailwind?

  1. 速度快 —— 不用在 HTML 和 CSS 文件之间来回跳了,样式一目了然。AI 写 Tailwind 也特别溜,因为它用标准化类名,不需要了解你的自定义 CSS 命名规范。
  2. 一致性好 —— 颜色、间距、字号都有固定比例,不会出现"这个按钮 12px 圆角,那个 15px"的混乱。
  3. 文件小 —— 自动删掉没用到的 CSS,最终打包通常只有几 KB。
  4. 响应式简单 —— 加个前缀就是不同屏幕尺寸的样式。

常用类名速查表

文字样式:

text-xs / text-sm / text-base / text-lg / text-xl / text-2xl / text-3xl → 字号
font-normal / font-medium / font-semibold / font-bold → 字重
text-gray-500 / text-blue-600 / text-red-500 → 颜色
text-center / text-left / text-right → 对齐

背景和颜色:

bg-white / bg-gray-100 / bg-blue-500 / bg-green-600 → 背景色
bg-gradient-to-r from-blue-500 to-purple-500 → 渐变背景
opacity-50 / opacity-75 → 透明度

Flexbox 布局:

flex → 启用 flex 布局
flex-row → 水平排列(默认)
flex-col → 垂直排列
justify-center → 水平居中
justify-between → 两端对齐
items-center → 垂直居中
gap-4 → 子元素间距

Grid 布局:

grid → 启用 grid
grid-cols-3 → 3 列等宽
grid-cols-[200px_1fr] → 自定义列宽
col-span-2 → 占 2 列

间距(最常用的):

p-4 / px-4 / py-4 / pt-4 / pr-4 / pb-4 / pl-4 → padding(内边距)
m-4 / mx-auto / mt-4 / mb-4 → margin(外边距)
gap-2 / gap-4 / gap-8 → 子元素间距
数字对应:1=4px, 2=8px, 3=12px, 4=16px, 6=24px, 8=32px

边框和圆角:

border / border-2 / border-gray-200 → 边框
rounded / rounded-lg / rounded-full → 圆角(从小到大)
shadow / shadow-lg / shadow-xl → 阴影

响应式(加前缀):

sm: → ≥640px(手机横屏)
md: → ≥768px(平板)
lg: → ≥1024px(笔记本)
xl: → ≥1280px(桌面)

用法:grid-cols-1 md:grid-cols-2 lg:grid-cols-3
意思是:手机1列,平板2列,桌面3列

实战:用 Tailwind 做一个卡片组件

function ProductCard() {
return (
<div className="bg-white rounded-2xl shadow-lg overflow-hidden max-w-sm">
{/* 图片 */}
<img
src="/product.jpg"
alt="产品图"
className="w-full h-48 object-cover"
/>

{/* 内容区 */}
<div className="p-6">
<span className="text-xs font-medium text-blue-600 bg-blue-50 px-2 py-1 rounded-full">
新品上市
</span>
<h3 className="text-xl font-bold text-gray-900 mt-3">
超好用的编程键盘
</h3>
<p className="text-gray-500 text-sm mt-2">
Cherry MX 红轴,打字手感丝滑,写代码效率翻倍。
</p>

{/* 价格和按钮 */}
<div className="flex items-center justify-between mt-4">
<span className="text-2xl font-bold text-red-500">¥299</span>
<button className="bg-blue-500 text-white px-5 py-2 rounded-lg hover:bg-blue-600 transition-colors">
加入购物车
</button>
</div>
</div>
</div>
);
}

没写一行 CSS 文件,但样式完整、响应式、甚至还有 hover 效果和过渡动画。这就是 Tailwind 的效率。

Dark Mode(暗黑模式)

Tailwind 内置暗黑模式支持,只需要加 dark: 前缀:

function DarkModeCard() {
return (
<div className="bg-white dark:bg-gray-800 rounded-xl p-6 shadow">
<h2 className="text-gray-900 dark:text-white text-xl font-bold">
支持暗黑模式的卡片
</h2>
<p className="text-gray-600 dark:text-gray-300 mt-2">
自动适应系统主题,也可以手动切换。
</p>
</div>
);
}

dark:bg-gray-800 的意思是:当系统处于暗黑模式时,背景用深灰色。你需要在 tailwind.config.ts 里设置策略:

// tailwind.config.ts
export default {
darkMode: "class", // 或 "media"(跟随系统)
// ...
};

Next.js + Tailwind:黄金搭档

这两个放在一起是目前最主流的组合。Next.js 的脚手架创建项目时直接内置了 Tailwind,开箱就能用。

分工非常清晰:Next.js 管"页面结构和数据逻辑",Tailwind 管"视觉样式"

它们搭配的典型写法:

// src/app/page.tsx — 首页
export default async function HomePage() {
const res = await fetch("https://api.example.com/stats");
const stats = await res.json();

return (
<div className="py-12">
{/* 标题区 */}
<div className="text-center mb-12">
<h1 className="text-5xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
欢迎来到我的网站
</h1>
<p className="text-gray-500 text-lg mt-4">
用 Next.js + Tailwind CSS 打造
</p>
</div>

{/* 数据卡片 */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-4xl mx-auto">
<StatCard title="用户数" value={stats.users} />
<StatCard title="文章数" value={stats.posts} />
<StatCard title="评论数" value={stats.comments} />
</div>
</div>
);
}

function StatCard({ title, value }: { title: string; value: number }) {
return (
<div className="bg-white rounded-xl shadow p-6 text-center hover:shadow-lg transition-shadow">
<p className="text-gray-500 text-sm">{title}</p>
<p className="text-3xl font-bold text-blue-600 mt-2">{value}</p>
</div>
);
}

简洁、清晰、可读。AI 生成这种代码的速度和质量都非常好。


其他值得了解的框架

Nuxt.js(Vue 生态的 Next.js): 如果你喜欢 Vue,Nuxt 是首选。它的理念和 Next.js 几乎一样——全栈、文件路由、SSR。Vue 的模板语法对某些人来说更直觉。但总体生态和 AI 支持不如 Next.js。

SvelteKit: Svelte 是个"编译时框架"——你的代码在打包时就被编译成原生 JS,运行时几乎没有框架开销。SvelteKit 是它的全栈版本。写起来非常简洁,性能极好。适合追求极致性能的项目,但生态相对小众。

Astro: 专注于内容型网站(博客、文档站、营销页)。它的杀手特性是零 JavaScript 默认——页面输出纯 HTML,只在需要交互的地方加载 JS。如果你要做的网站以展示内容为主,Astro 是性能最优解。

怎么选?

框架生态AI 支持适合场景
Next.js⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐通用 Web 应用,首选
Nuxt.js⭐⭐⭐⭐⭐⭐⭐喜欢 Vue 的团队
SvelteKit⭐⭐⭐⭐⭐⭐追求极致性能
Astro⭐⭐⭐⭐⭐⭐内容/文档网站

什么时候不该用 Next.js?

Next.js 很强,但不是万能的。以下场景你可能不需要它:

1. 非常简单的静态页面 —— 就一个落地页,几个展示图,没有动态内容。直接写 HTML + Tailwind,用 Vercel 或 Netlify 部署就行,没必要引入整个 Next.js。

2. 内部工具/管理后台 —— 不需要 SEO,不需要 SSR,用 Vite + React 更轻量、更快。

3. 纯内容/博客站 —— Astro 或 Hugo 可能更合适,输出纯 HTML,性能碾压。

4. 移动端 App —— Next.js 是 Web 框架。做 App 用 React Native、Flutter 或 Swift/Kotlin。

5. 学习目的想从零理解 —— 如果你想深入理解 React 本身,先用 Vite + React 裸写,搞清楚原理再上框架。


总结

框架不是信仰,是工具。但选对工具能让你事半功倍:

  • 新手起步:Next.js + Tailwind CSS,这是 2024-2025 年的"标准答案"
  • 核心原则:Server Component 优先,需要交互才用 Client Component
  • AI 时代:主流框架 = AI 生成代码的质量和准确度更高
  • 别纠结:选一个最顺手的,赶紧开始做东西才是正经事