3.2 现代开发框架
为什么需要框架?
想象一下你要做一顿饭。
方式一:从零开始。 你去菜市场买菜、洗菜、切菜、调料、掌握火候……每一环节都自己来。做一顿饭可能要两小时,而且味道好不好全靠经验。
方式二:用预制菜/料理包。 食材洗好切好了,调料配好了,你只需要下锅炒几分钟。速度快,味道稳定,虽然灵活性差一点,但对大多数人来说足够好了。
框架就是编程世界的"料理包"。
理论上你可以用纯 HTML、CSS、JavaScript 手搓一个网站出来。但你会发现——写到第三页就开始崩溃了。每个页面都重复一堆导航栏代码,改个颜色要在十个文件里改,页面切换的时候整页刷新白屏闪一下……
框架帮你把这些"重复、通用、烦人"的事情都封装好了。路由、状态管理、样式方案、构建打包、性能优化……开箱即用。
为什么 AI 编程时代框架更关键? 因为 AI 对流行框架的理解最深、生成的代码质量最高。你让 AI 写一个 Next.js 的页面,它大概率写得又快又好;你让它写一个冷门框架的代码,它可能一本正经地胡说八道。选主流框架 = 让 AI 发挥最大能力。
Next.js:全栈开发的瑞士军刀
什么是 Next.js?
Next.js 是目前最推荐的 Web 开发框架,没有之一。它是基于 React 构建的,但比 React 多了一大堆"开箱即用"的能力。
为什么选它? 四个理由:
- 全栈框架 —— 前端页面和后端 API 在同一个项目里,不用维护两套代码。就像你不需要单独租一个厨房了,Next.js 给你的是一个"前厅带厨房"的商铺。
- Vercel 生态 —— Next.js 背后的公司 Vercel 有最好用的部署平台。代码推到 GitHub,自动部署上线,免费额度对个人项目绰绰有余。
- AI 友好 —— 目前 AI 编程工具(Cursor、Claude Code 等)对 Next.js 的支持最好,生成的代码能直接跑。
- 性能优秀 —— 自动代码分割、图片优化、服务端渲染,不用你手动优化。
创建项目
打开终端,一行命令搞定:
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.tsx | 404 页面 | 可选 |
页面和路由(文件即路由)
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
- 不能用
useState、useEffect、事件监听(onClick 等) - 适合:展示数据、获取内容、不需要交互的页面
Client Components(客户端组件):
- 在浏览器里渲染,可以交互
- 需要在文件顶部加
"use client"声明 - 可以用
useState、useEffect、事件监听 - 适合:表单、按钮点击、实时更新、动画
怎么选择? 简单原则:默认用 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?
- 速度快 —— 不用在 HTML 和 CSS 文件之间来回跳了,样式一目了然。AI 写 Tailwind 也特别溜,因为它用标准化类名,不需要了解你的自定义 CSS 命名规范。
- 一致性好 —— 颜色、间距、字号都有固定比例,不会出现"这个按钮 12px 圆角,那个 15px"的混乱。
- 文件小 —— 自动删掉没用到的 CSS,最终打包通常只有几 KB。
- 响应式简单 —— 加个前缀就是不同屏幕尺寸的样式。
常用类名速查表
文字样式:
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 生成代码的质量和准确度更高
- 别纠结:选一个最顺手的,赶紧开始做东西才是正经事