Định tuyến
Chia ứng dụng thành các route có layout dùng chung, liên kết kèm phím tắt và lịch sử.
Trong chương này
- Tệp là route
- Layout dùng chung
- Quay lại
- Phân đoạn động
App Router ánh xạ các tệp trong app/ tới URL, theo quy ước của Next.js App Router. Thanh địa chỉ và lịch sử của trình duyệt luôn đồng bộ, nên thao tác quay lại, tiến tới và liên kết sâu vẫn hoạt động khi giao diện render trong console.
Tệp là route
Chuyển danh sách sang route riêng và thêm trang cài đặt:
app/ layout.tsx page.tsx → /Đã thêm: deployments/Đã thêm: page.tsx → /deploymentsĐã thêm: [id]/page.tsx → /deployments/dpl_8fK2Đã thêm: settings/Đã thêm: page.tsx → /settingsLayout dùng chung
layout.tsx bọc mọi trang và giữ trạng thái khi chuyển trang. Đặt thanh trên cùng và phần điều hướng vào đó.
Đã thêm: import type { ReactNode } from "react";Đã thêm: import { Box, Spacer, Text } from "@textjs/app";Đã thêm: import Link from "@textjs/app/link";Đã thêm: import { usePathname } from "@textjs/app/navigation";Đã thêm: Đã thêm: export const metadata = { title: { default: "Acme Deploys", template: "%s · Acme" } };Đã thêm: Đã thêm: export default function RootLayout({ children }: { children?: ReactNode }) {Đã thêm: const pathname = usePathname();Đã thêm: return (Đã thêm: <Box className="flex-col grow">Đã thêm: <Box className="flex-row h-1 px-1 gap-2">Đã thêm: <Text bold>▼ Acme</Text>Đã thêm: <Text color="subtle">{`acme.local${pathname === "/" ? "" : pathname}`}</Text>Đã thêm: <Spacer />Đã thêm: </Box>Đã thêm: <Box className="flex-row h-1 px-1 gap-3">Đã thêm: <Link href="/" shortcut="1">Overview</Link>Đã thêm: <Link href="/deployments" shortcut="2">Deployments</Link>Đã thêm: <Link href="/settings" shortcut="3">Settings</Link>Đã thêm: </Box>Đã thêm: <Box className="flex-col grow p-1">{children}</Box>Đã thêm: </Box>Đã thêm: );Đã thêm: }shortcut gán một phím cho liên kết. Nhấn 1, 2 và 3 trong console; URL của ứng dụng thực tế sẽ thay đổi theo từng phím.
Quay lại
useRouter() điều hướng từ mã. Gắn Backspace với router.back() trong layout:
Đã xóa: import { Box, Spacer, Text } from "@textjs/app";Đã thêm: import { Box, Spacer, Text, useInput } from "@textjs/app";import Link from "@textjs/app/link";Đã xóa: import { usePathname } from "@textjs/app/navigation";Đã thêm: import { usePathname, useRouter } from "@textjs/app/navigation";export default function RootLayout({ children }: { children?: ReactNode }) { const pathname = usePathname();Đã thêm: const router = useRouter();Đã thêm: Đã thêm: useInput((e) => {Đã thêm: if (e.key === "backspace") router.back();Đã thêm: });Phân đoạn động
Thư mục [id] nhận giá trị trong params:
import { Text, type PageProps } from "@textjs/app";export default function DeploymentPage({ params }: PageProps<{ id: string }>) { return <Text bold>{params.id}</Text>;}Trên máy chủ lưu trữ tĩnh, phân đoạn động như thế này cần quy tắc viết lại URL về index.html. Chương 10 trình bày nội dung này.
Dùng thử
Đây là Acme Deploys ở cuối chương, đang chạy trong DevTools. Nhấp vào vùng focus, rồi dùng các phím bên dưới.
Mở console
Ứng dụng render trong DevTools.Trước tiên bật “Hiển thị tính năng cho nhà phát triển web” trong Cài đặt Safari → Nâng cao. Sau đó nhấp vào đây và nhấn 2.
Mở trên máy tính
Ứng dụng này render trong console của DevTools, cần trình duyệt trên máy tính.
Bài trắc nghiệm
2 câu hỏiTrả lời mọi câu hỏi để hoàn thành chương.