nextjs学习2:app router

本文是基于 nextjs v14 版本进行展示。

最快捷的创建 Next.js 项目的方式是使用 create-next-app脚手架,你只需要运行:

js 复制代码
npx create-next-app@14

推荐使用 tailwindcss ,这也是 Next.js 推荐的 CSS 方案,很多 example 都会用它。

运行项目

查看项目根目录 package.json 文件的代码:

js 复制代码
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }

开发的时候使用 npm run dev。部署的时候先使用 npm run build 构建生产代码,再执行 npm run start 运行生产项目。运行 npm run lint 则会执行 ESLint 语法检查。

next build

执行 next build 将会创建项目的生产优化版本:

从上图可以看出,构建时会输出每条路由的信息,比如 Size 和 First Load JS。注意这些值指的都是 gzip 压缩后的大小。其中 First Load JS 会用绿色、黄色、红色表示,绿色表示高性能,黄色或红色表示需要优化。

这里要解释一下 Size 和 First Load JS 的含义。

正常我们开发的 Next.js 项目,其页面表现类似于单页应用,即路由跳转(我们称之为"导航")的时候,页面不会刷新,而会加载目标路由所需的资源然后展示,所以:

js 复制代码
加载目标路由一共所需的 JS 大小 = 每个路由都需要依赖的 JS 大小(shared by all) + 目标路由单独依赖的 JS 大小

其中:

  • 加载目标路由一共所需的 JS 大小就是 First Load JS
  • 目标路由单独依赖的 JS 大小就是 Size
  • 每个路由都需要依赖的 JS 大小就是图中单独列出来的 First load JS shared by all

以上图中的 / 路由地址为例,87.6 kB(First Load JS)= 533 B(Size) + 87.1 kB(First load JS shared by all)

next start

生产模式下,使用 next start运行程序。不过要先执行 next build构建出生产代码。运行的时候,跟开发模式相同,程序默认开启在 http://localhost:3000。如果你想更改端口号:

js 复制代码
npx next start -p 4000

app Router

app router 的目录结构类似于:

js 复制代码
src/
└── app
    ├── page.js 
    ├── layout.js
    ├── template.js
    ├── loading.js
    ├── error.js
    └── not-found.js
    ├── about
    │   └── page.js
    └── more
        └── page.js

定义路由(Routes)

首先是定义路由,文件夹被用来定义路由。

每个文件夹都代表一个对应到 URL 片段的路由片段。创建嵌套的路由,只需要创建嵌套的文件夹。举个例子,下图的 app/dashboard/settings目录对应的路由地址就是 /dashboard/settings

定义页面(Pages)

那如何保证这个路由可以被访问呢?你需要创建一个特殊的名为 page.js 的文件。至于为什么叫 page.js呢?除了 page 有"页面"这个含义之外,你可以理解为这是一种约定或者规范。

  • app/page.js 对应路由 /
  • app/dashboard/page.js 对应路由 /dashboard
  • app/dashboard/settings/page.js 对应路由/dashboard/settings
  • analytics 目录下因为没有 page.js 文件,所以没有对应的路由。这个文件可以被用于存放组件、样式表、图片或者其他文件。

page.js 的代码该如何写呢?最常见的是展示 UI,比如:

js 复制代码
// app/page.js
export default function Page() {
  return <h1>Hello, Next.js!</h1>
}

定义布局(Layouts)

布局是指多个页面共享的 UI。

在导航的时候,布局会保留状态、保持可交互性并且不会重新渲染,比如用来实现后台管理系统的侧边导航栏。

定义一个布局,你需要新建一个名为 layout.js的文件,该文件默认导出一个 React 组件,该组件应接收一个 children prop,chidren 表示子布局(如果有的话)或者子页面。

举个例子,我们新建目录和文件如下图所示:

相关代码如下:

js 复制代码
// app/dashboard/layout.js
export default function DashboardLayout({
  children,
}) {
  return (
    <section>
      <nav>nav</nav>
      {children}
    </section>
  )
}

// app/dashboard/page.js
export default function Page() {
  return <h1>Hello, Dashboard!</h1>
}

同一文件夹下如果有 layout.js 和 page.js,page 会作为 children 参数传入 layout。换句话说,layout 会包裹同层级的 page。

定义加载界面(Loading UI)

dashboard 目录下我们新建一个 loading.js

loading.js的代码如下:

js 复制代码
// app/dashboard/loading.js
export default function DashboardLoading() {
  return <>Loading dashboard...</>
}

同级的 page.js 代码如下:

js 复制代码
// app/dashboard/page.js
async function getData() {
  await new Promise((resolve) => setTimeout(resolve, 3000))
  return {
    message: 'Hello, Dashboard!',
  }
}

# 一定要是async定义的组件,不然loading.js不会生效
export default async function DashboardPage(props) {
  const { message } = await getData()
  return <h1>{message}</h1>
}

不再需要其他的代码,loading 的效果就实现了。

就是这么简单。其关键在于 page.js导出了一个 async 函数

loading.js 的实现原理是将 page.js和下面的 children 用 <Suspense> 包裹。因为page.js导出一个 async 函数,Suspense 得以捕获数据加载的 promise,借此实现了 loading 组件的关闭。

定义 404 页面

顾名思义,当该路由不存在的时候展示的内容。

Next.js 项目默认的 not-found 效果如下:

如果你要替换这个效果,只需要在 app 目录下新建一个 not-found.js,代码示例如下:

相关推荐
小p4 小时前
nextjs学习3:动态路由、路由组、平行路由
next.js
ybc46521 天前
React、Next安全漏洞问题修复和自测
前端·安全·next.js
小满zs2 天前
Next.js第十八章(静态导出SSG)
前端·next.js
白雾茫茫丶2 天前
动态配色方案:在 Next.js 中实现 Shadcn UI 主题色切换
react.js·next.js
小满zs5 天前
Next.js第十七章(Script脚本)
前端·next.js
小满zs5 天前
Next.js第十六章(font字体)
前端·next.js