基本概念
在 Next.js 14 中,app
目录引入了一种新的文件系统路由方式,相比于传统的 pages
目录,这种方式更加灵活,支持更强大的布局和组件化能力。以下是详细的说明和示例。
- 在
app
目录中,每个文件和文件夹都对应一个 URL 路径。Next.js 自动将文件系统结构映射为应用的路由,无需手动配置。
定义页面路由
app/ ├── page.js -> "/" ├── about/ │ └── page.js -> "/about" └── blog/ └── page.js -> "/blog"
app/page.js
定义了根路径/
的页面。app/about/page.js
定义了/about
路径的页面。app/blog/page.js
定义了/blog
路径的页面。
动态路由
在 app
目录中,通过方括号 []
定义动态路由。
app/ └── blog/ ├── [id]/ │ └── page.js -> "/blog/:id" └── page.js -> "/blog"
在 app/blog/[id]/page.js
文件中,id
是一个动态参数,可以在页面组件中通过 useRouter
钩子获取
// app/blog/[id]/page.js import { useRouter } from 'next/navigation'; export default function BlogPost() { const router = useRouter(); const { id } = router.query; return ( <div> <h1>Blog Post ID: {id}</h1> </div> ); }
嵌套路由 和 布局
app
目录支持嵌套路由和布局管理。通过在不同层级的文件夹中定义 layout.js
,可以为该层级及其子路由提供共享的布局。
app/ ├── layout.js -> 应用级别布局 ├── about/ │ └── layout.js -> about 页面及其子页面的布局 ├── blog/ │ ├── layout.js -> blog 页面及其子页面的布局 │ ├── [id]/ │ │ └── page.js -> "/blog/:id" │ └── page.js -> "/blog" └── page.js -> 首页 "/"
/blog
和 /blog/:id
页面将共享 app/blog/layout.js
中定义的布局。
路由参数处理
通过useSearchParams
钩子来获取这些查询参数
例如 url
为 /search?q=nextjs
// app/search/page.js import { useSearchParams } from 'next/navigation'; export default function SearchPage() { const searchParams = useSearchParams(); const query = searchParams.get('q'); return ( <div> <h1>Search Query: {query}</h1> </div> ); }
捕获所有路由和可选捕获
捕获所有路由:
定义一个捕获所有路由的页面,例如 /blog/[...slug]
对应的 app/blog/[...slug]/page.js
文件,它将匹配 /blog/a
, /blog/a/b
等路径。
可选捕获路由:
使用 [[...slug]]
可以定义一个可选的捕获路由。如果没有匹配的段,路径会默认为 /blog
。
// app/blog/[[...slug]]/page.js import { useRouter } from 'next/navigation'; export default function Blog() { const router = useRouter(); const { slug } = router.query; if (!slug) { return <div>Blog Home Page</div>; } return <div>Blog Post: {slug.join('/')}</div>; }