如何创建布局和页面
Next.js 使用基于文件系统的路由,这意味着你可以使用文件夹和文件来定义路由。本页将指导你如何创建布局和页面,以及它们之间的链接。
创建页面
页面是在特定路由上渲染的 UI。要创建页面,请在 app
目录中添加一个 page
文件,并默认导出一个 React 组件。例如,要创建索引页 (/
)


export default function Page() {
return <h1>Hello Next.js!</h1>
}
创建布局
布局是在多个页面之间共享的 UI。在导航时,布局会保留状态,保持交互性,并且不会重新渲染。
你可以通过从 layout
文件默认导出一个 React 组件来定义布局。该组件应接受一个 children
属性,它可以是一个页面或另一个 布局。
例如,要创建一个接受索引页作为子级的布局,请在 app
目录中添加一个 layout
文件


export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
<main>{children}</main>
</body>
</html>
)
}
上面的布局称为根布局,因为它是在 app
目录的根目录中定义的。根布局是必需的,并且必须包含 html
和 body
标签。
创建嵌套路由
嵌套路由是由多个 URL 段组成的路由。例如,/blog/[slug]
路由由三个段组成
/
(根段)blog
(段)[slug]
(叶子段)
在 Next.js 中
- 文件夹用于定义映射到 URL 段的路由段。
- 文件(如
page
和layout
)用于创建为段显示的 UI。
要创建嵌套路由,你可以将文件夹相互嵌套。例如,要为 /blog
添加路由,请在 app
目录中创建一个名为 blog
的文件夹。然后,要使 /blog
公开访问,请添加一个 page
文件


import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'
export default async function Page() {
const posts = await getPosts()
return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}
你可以继续嵌套文件夹以创建嵌套路由。例如,要为特定博客文章创建路由,请在 blog
中创建一个新的 [slug]
文件夹并添加一个 page
文件


function generateStaticParams() {}
export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}
须知:将文件夹名称括在方括号中(例如
[slug]
)会创建一个特殊的动态路由段,用于从数据生成多个页面。这对于博客文章、产品页面等非常有用。
嵌套布局
默认情况下,文件夹层次结构中的布局也是嵌套的,这意味着它们通过其 children
属性包装子布局。你可以通过在特定路由段(文件夹)内添加 layout
来嵌套布局。
例如,要为 /blog
路由创建布局,请在 blog
文件夹中添加一个新的 layout
文件。


export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
如果要组合上面的两个布局,根布局 (app/layout.js
) 将包装博客布局 (app/blog/layout.js
),而博客布局将包装博客 (app/blog/page.js
) 和博客文章页面 (app/blog/[slug]/page.js
)。
页面之间链接
你可以使用 <Link>
组件 在路由之间导航。<Link>
是一个内置的 Next.js 组件,它扩展了 HTML <a>
标签,以提供预取和客户端导航。
例如,要生成博客文章列表,请从 next/link
导入 <Link>
并将 href
属性传递给组件
import Link from 'next/link'
export default async function Post({ post }) {
const posts = await getPosts()
return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
<Link>
是在你的 Next.js 应用程序中路由之间导航的主要和推荐方式。但是,你也可以使用 useRouter
hook 进行更高级的导航。
API 参考
这有帮助吗?