在 Next.js 中,使用 [id] 或 public 作为文件夹或文件名是两种完全不同的概念,分别对应 动态路由 和 静态资源托管。以下是详细解释:
1. [id] 风格:动态路由(Dynamic Routes)
作用
Next.js 的动态路由允许你创建基于参数的灵活页面路径,例如 /posts/1、/users/abc 等。通过在文件夹或文件名中使用方括号 [],可以捕获 URL 中的动态片段。
使用场景
- 博客文章详情页(如
/posts/[slug]) - 用户个人主页(如
/users/[id]) - 任何需要根据 ID 或参数加载数据的页面
示例
文件夹结构
pages/
posts/
[slug].js # 匹配 /posts/any-slug
index.js # 匹配 /posts (可选)
users/
[id]/
index.js # 匹配 /users/123
profile.js # 匹配 /users/123/profile (嵌套动态路由)
代码示例(pages/users/[id].js)
jsx
import { useRouter } from 'next/router';
export default function UserPage() {
const router = useRouter();
const { id } = router.query; // 获取 URL 中的 id 参数
return <div>User ID: {id}</div>;
}
访问 URL
/users/123→ 渲染UserPage,id = "123"/users/abc→ 渲染UserPage,id = "abc"
2. public 文件夹:静态资源托管
作用
Next.js 的 public 文件夹用于存放静态资源(如图片、字体、机器人文件等),这些文件会被直接复制到构建输出的根目录,并通过绝对路径访问。
使用场景
- 项目 logo、favicon
- 公开可访问的 JSON 数据
- 机器人文件(
robots.txt、sitemap.xml)
示例
文件夹结构
public/
images/
logo.png
favicon.ico
robots.txt
访问方式
- 图片:
http://localhost:3000/images/logo.png - Favicon:
http://localhost:3000/favicon.ico - 机器人文件:
http://localhost:3000/robots.txt
注意事项
- 无需导入 :
public中的文件可以直接通过 URL 引用,无需在代码中导入。 - 避免命名冲突 :不要将
public中的文件名与pages下的路由重名(例如,不要有public/about.js和pages/about.js)。
3. 关键区别
| 特性 | [id] 动态路由 |
public 文件夹 |
|---|---|---|
| 用途 | 创建基于参数的动态页面 | 托管静态资源 |
| 路径规则 | 方括号 [] 捕获动态片段 |
文件直接映射到根路径 |
| 代码访问方式 | 通过 router.query 获取参数 |
通过 URL 直接访问(无需代码处理) |
| 典型文件 | [slug].js、[id]/index.js |
logo.png、robots.txt |
4. 常见问题
Q1: 可以嵌套动态路由吗?
可以!例如:
pages/
users/
[id]/
posts/
[postId].js # 匹配 /users/123/posts/456
Q2: public 中的文件会被预渲染吗?
不会 。public 中的文件是纯静态资源,Next.js 不会对其进行任何处理(如预渲染、API 路由等)。
Q3: 动态路由和 public 能结合使用吗?
可以,但用途不同。例如:
-
动态页面(
[id].js)可以引用public中的图片:jsx<img src="/images/logo.png" alt="Logo" />
总结
[id]:用于动态路由,通过方括号捕获 URL 参数,适合数据驱动的页面。public:用于静态资源,文件直接暴露在根路径,适合图片、配置文件等。
这两种风格是 Next.js 路由和资源管理的核心特性,合理使用可以高效构建现代化应用!