Skip to content

Next.js 入门

创建应用

使用 npm 创建 Next.js 应用:

bash
npx create-next-app@latest

使用哪种包管理器,依赖也会使用相应的包管理器安装。例如,使用 pnpm 创建 Next.js 应用:

bash
pnpm dlx create-next-app@latest

推荐全部使用默认配置,然后将自动安装依赖。

项目结构

目录或文件说明
app/App 路由(Next.js 13 之后的新路由方式)
pages/Pages 路由(经典的路由方式,不推荐)
public/静态文件
src/源文件

项目可以使用 next.config.{cjs|cts|mjs|mts|js|ts} 配置文件。

TypeScript 支持的配置文件

只有 Next.js 15 以后的版本才能使用有 TypeScript 支持的配置文件,详情见 讨论#35969,Next.js 14 推荐使用 .mjs 配置项目。

例如,下面是 next.config.mjs 的配置文件:

js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true
}

export default nextConfig

定义路由

路由方式

本文只介绍 App 路由的定义方式,不再介绍 Pages 路由的任何细节。

页面(Pages)

使用 page.{js|jsx|ts|tsx} 文件声明一个页面路由。

tsx
export default function Page() {
  return <h1>Hello, World!</h1>;
}

默认情况下,所有组件都是服务端组件,也就是页面的渲染是在服务端完成的。这样对于 SEO 和客户端渲染的性能都有很大的优势。但是有很多情况下,我们使用的第三方 UI 组件库都不支持服务端渲染,因此我们需要使用客户端组件。

在文件的开头,使用 'use client' 声明一个客户端组件。

布局(Layouts)

使用 layout.{js|jsx|ts|tsx} 文件声明一个页面布局。

tsx
export default function DashboardLayout({
  children, // 可能是页面或者嵌套的布局
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* 在这里定义共享的 UI 内容 */}
      <nav></nav>
 
      {children}
    </section>
  )
}

布局是可选的,但项目必须有一个根布局,如 app/layout.tsx。根布局必须包含 <html><body> 标签。根布局用于定义全局的布局和样式。

tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <main>{children}</main>
      </body>
    </html>
  )
}

布局是可嵌套的,在不同的页面路由中都可以添加 layout.{js|jsx|ts|tsx} 文件来定义路由。

布局和布局、布局和页面之间都 不能 传递数据。

模板(Templates)

模板和布局类似,不同的是布局会在页面之间共享,但对于每个页面来说都有一个模板。所以模板不会保留公共状态,在路由切换的时候会重新渲染一个新的模板来包装页面。

如果你有一些 Effects 或组件需要在路由之间进行重置,可以使用模板。

使用 template.{js|jsx|ts|tsx} 文件声明一个页面模板。

tsx
export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}

模板将渲染在布局和页面之间,下面是一个渲染结构的示例:

tsx
<Layout>
  {/* 每个模板都有一个唯一的键 */}
  <Template key={routeParam}>
    {/* 页面内容 */}
    {children}
  </Template>
</Layout>

路由处理程序(Route Handlers)

路由处理程序即后端,用于处理数据请求并返回。它的路由规则和页面路由一致,使用 route.{js|ts} 文件声明一个路由处理程序。

ts
export async function GET(request: Request) {}

通过导出不同的函数来定义不同的接口方法,目前支持 GETPOSTPUTPATCHDELETEHEADOPTIONS 方法。

如果请求了没有定义的路由处理程序将返回 405 Method Not Allowed