路由

将应用拆分为路由,共用布局,支持带快捷键的链接和历史记录。

本章应用正在你的控制台中运行。按 ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C 打开控制台(先开启开发者功能),然后试用。
观看本章3:46

本章内容

  • 文件即路由
  • 共享布局
  • 后退
  • 动态路由段

App Router 遵循 Next.js App Router 的约定,将 app/ 中的文件映射到 URL。浏览器的地址栏和历史记录保持同步,因此在控制台渲染 UI 时,后退、前进和深层链接仍然可用。

文件即路由

将列表移到独立的路由中,并添加一个设置页面:

app/+5text
app/  layout.tsx  page.tsx                 → /新增:  deployments/新增:    page.tsx               → /deployments新增:    [id]/page.tsx          → /deployments/dpl_8fK2新增:  settings/新增:    page.tsx               → /settings

共享布局

layout.tsx 包裹每个页面,并在导航时保留自身状态。将顶部栏和导航放在其中。

app/layout.tsx+25tsx
新增:import type { ReactNode } from "react";新增:import { Box, Spacer, Text } from "@textjs/app";新增:import Link from "@textjs/app/link";新增:import { usePathname } from "@textjs/app/navigation";新增:新增:export const metadata = { title: { default: "Acme Deploys", template: "%s · Acme" } };新增:新增:export default function RootLayout({ children }: { children?: ReactNode }) {新增:  const pathname = usePathname();新增:  return (新增:    <Box className="flex-col grow">新增:      <Box className="flex-row h-1 px-1 gap-2">新增:        <Text bold>▼ Acme</Text>新增:        <Text color="subtle">{`acme.local${pathname === "/" ? "" : pathname}`}</Text>新增:        <Spacer />新增:      </Box>新增:      <Box className="flex-row h-1 px-1 gap-3">新增:        <Link href="/" shortcut="1">Overview</Link>新增:        <Link href="/deployments" shortcut="2">Deployments</Link>新增:        <Link href="/settings" shortcut="3">Settings</Link>新增:      </Box>新增:      <Box className="flex-col grow p-1">{children}</Box>新增:    </Box>新增:  );新增:}

shortcut 将单个按键绑定到链接。在控制台中按下 1、2 和 3;在真实应用中,每次按键都会改变 URL。

后退

useRouter() 用于在代码中导航。在布局中将 Backspace 绑定到 router.back():

app/layout.tsx+7-2tsx
移除:import { Box, Spacer, Text } from "@textjs/app";新增:import { Box, Spacer, Text, useInput } from "@textjs/app";import Link from "@textjs/app/link";移除:import { usePathname } from "@textjs/app/navigation";新增:import { usePathname, useRouter } from "@textjs/app/navigation";export default function RootLayout({ children }: { children?: ReactNode }) {  const pathname = usePathname();新增:  const router = useRouter();新增:新增:  useInput((e) => {新增:    if (e.key === "backspace") router.back();新增:  });

动态路由段

[id] 文件夹通过 params 接收对应的值:

app/deployments/[id]/page.tsxtsx
import { Text, type PageProps } from "@textjs/app";export default function DeploymentPage({ params }: PageProps<{ id: string }>) {  return <Text bold>{params.id}</Text>;}

在静态托管服务上,这样的动态路由段需要重写到 index.html。第 10 章会介绍这一点。

试用

这是本章结束时的 Acme Deploys,正在 DevTools 中运行。点击输入区,然后使用下列按键。

▼ 05 · 路由

打开控制台

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

应用在 DevTools 中渲染。先在 Safari 设置 → 高级中开启“显示网页开发者功能”。 然后点击这里并按 2。

在桌面端打开

此应用在 DevTools 控制台中渲染,需要桌面浏览器。

测验

2 个问题

回答所有问题以完成本章。

/deployments 路径渲染哪个文件?

 

页面间导航时会保留什么?