路由

將應用程式分成多個路由,共用版面配置,並支援連結、快速鍵與歷史記錄。

本章的應用程式正在你的主控台執行。按 ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C 開啟主控台(先啟用開發者功能),然後試用。
觀看本章3:46

本章內容

  • 檔案即路由
  • 共用版面配置
  • 返回上一頁
  • 動態區段

App Router 遵循 Next.js App Router 慣例,將 app/ 中的檔案對應至網址。瀏覽器的網址列與歷史記錄會保持同步,因此即使 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;在實際的應用程式中,每個按鍵都會讓網址隨之變更。

返回上一頁

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 渲染?

 

在頁面之間導覽時,什麼會保留?