当前位置: 首页 > news >正文

Next.js 的客户端页面路由详解

文章目录

    • 1. 路由的基本概念
    • 2. 客户端路由的核心
      • (1) `useRouter`
      • (2) `<Link />` 组件
      • (3) `redirect()`
    • 3. 动态路由与客户端获取参数
    • 4. 客户端路由和服务端路由的区别
    • 5. 路由案例
      • 1. `app/layout.tsx` (全局布局)
      • 2. `app/components/NavBar.tsx` (导航栏)
      • 3. `app/page.tsx` (首页)
      • 4. `app/blog/[id]/page.tsx` (详情页)
      • 效果

1. 路由的基本概念

Next.js 15(App Router 模式)中,路由主要依赖文件系统路由(File-system routing),所有页面都放在app/目录下:

app/ ├── page.tsx // 对应 "/" ├── about/ │ └── page.tsx // 对应 "/about" └── blog/ └── [id]/ └── page.tsx // 动态路由 "/blog/123"
  • 服务端渲染 (SSR):页面初次加载时由服务器返回 HTML。
  • 客户端路由 (CSR):在页面之间跳转时,Next.js使用客户端路由器(基于 React Router-like 机制)来实现无刷新切换

2. 客户端路由的核心

客户端路由由next/navigation提供,主要用到两个Hook / API

(1)useRouter

用于编程式导航,和 React Router 的useNavigate类似。

"use client";import{useRouter}from"next/navigation";exportdefaultfunctionHome(){constrouter=useRouter();return<button onClick={()=>router.push("/about")}>去 About 页面</button>;}
  • router.push("/path"):跳转到某个页面,保留历史记录。
  • router.replace("/path"):跳转但不保留历史记录。
  • router.back():回退。

(2)<Link />组件

推荐使用<Link>来实现预加载和无刷新跳转

importLinkfrom"next/link";exportdefaultfunctionNavBar(){return(<nav><Link href="/">首页</Link><Link href="/about">关于我们</Link></nav>);}
  • <Link>默认会预加载目标页面的代码,提高切换速度。
  • 只有当目标在视口中可见时才会自动预加载。

(3)redirect()

用于服务端或客户端强制重定向。

import{redirect}from"next/navigation";exportdefaultfunctionPage(){constisLogin=false;if(!isLogin){redirect("/login");}return<div>已登录</div>;}

3. 动态路由与客户端获取参数

动态路由文件夹[id]会捕获 URL 中的参数。

文件夹嵌套结构:app/blog/[id]/page.tsx如下:

app/ ├── blog/ │ └── [id]/ │ └── page.tsx // 动态路由 "/blog/123"

组件获取如下:

// app/blog/[id]/page.tsx"use client";import{useParams}from"next/navigation";exportdefaultfunctionBlogPage(){constparams=useParams();// { id: "123" }return<h1>文章ID:{params.id}</h1>;}// 如果是 服务端渲染,直接通过 `params` 获取:exportdefaultfunctionBlogPage({params}:{params:{id:string}}){return<h1>文章ID:{params.id}</h1>;}

上面这种方式只能获取一层动态路由参数,不能获取嵌套路由参数(例如/blog/123/comment/456就报错了)。

路由结构改用[...id]如下:

app/ ├── blog/ │ └── [...id]/ │ └── page.tsx // 动态路由 "/blog/123/comment/456"

这样就可以获取到多层动态路由参数了。

还有一种情况我们想让这个路由参数是可选的,有没有都可以,那么在外层再包裹一层中括号变成了[[...id]],如下:

app/ ├── blog/ │ └── [[...id]]/ │ └── page.tsx // 动态路由 "/blog/123/comment/456"

动态路由总结:

  • [id]:只能获取一层路由参数,例如/blog/123
  • [...id]:可以获取多层路由参数,例如/blog/123/comment/456
  • [[...id]]:路由参数是可选的,有没有都可以,例如/blog/123/blog/123/comment/456

4. 客户端路由和服务端路由的区别

特性服务端渲染 (SSR)客户端路由 (CSR)
初次加载服务器生成 HTML前端只加载入口 HTML
跳转整页刷新 / SSR无刷新跳转,速度快
数据获取通过fetch()/server actionsuseEffect/ SWR / TanStack Query
SEO较弱(需 SSR/ISR 支持)

Next.js 的优势就是两者结合—— 初次请求走 SSR,后续页面切换走 CSR。

5. 路由案例

整个案例包含:

  • 首页/:有一个跳转按钮,去详情页
  • 详情页/blog/[id]:显示文章 ID
  • 导航栏组件:全局无刷新跳转

项目结构

app/ ├── layout.tsx ├── page.tsx // 首页 ├── blog/ │ └── [id]/ │ └── page.tsx // 动态详情页 └── components/ └── NavBar.tsx // 导航栏

1.app/layout.tsx(全局布局)

import"./globals.css";importNavBarfrom"./components/NavBar";exportdefaultfunctionRootLayout({children}:{children:React.ReactNode}){return(<html lang="en"><body><NavBar/><main>{children}</main></body></html>);}

2.app/components/NavBar.tsx(导航栏)

"use client";importLinkfrom"next/link";exportdefaultfunctionNavBar(){return(<nav style={{display:"flex",gap:"20px",marginBottom:"20px"}}><Link href="/">首页</Link><Link href="/blog/123">文章123</Link><Link href="/blog/456">文章456</Link></nav>);}

3.app/page.tsx(首页)

"use client";import{useRouter}from"next/navigation";exportdefaultfunctionHomePage(){constrouter=useRouter();return(<div><h1>首页</h1><button onClick={()=>router.push("/blog/999")}style={{marginTop:"20px"}}>去文章999</button></div>);}

4.app/blog/[id]/page.tsx(详情页)

"use client";import{useParams,useRouter}from"next/navigation";exportdefaultfunctionBlogDetail(){constparams=useParams();// { id: "123" }constrouter=useRouter();return(<div><h1>文章详情</h1><p>当前文章ID:{params.id}</p><button onClick={()=>router.back()}>返回上一页</button></div>);}

效果

  1. 打开/→ 首页

    • 可以点击「去文章 999」按钮 → 跳转/blog/999
  2. 在导航栏点击/blog/123/blog/456→ 跳转不同文章详情

  3. 在详情页点「返回上一页」 → 回到首页


🚀 感谢阅读!想了解更多?

📖 我的博客网站 | 记录思考,分享干货
🏡 我的个人主页 | 关于我、开源项目


http://www.cnnetsun.cn/news/4213556.html

相关文章:

  • Redis五大核心数据结构详解:从缓存到数据结构服务器的进阶指南
  • 从通用模型到专业定制:AI应用从“龙虾”到“爱马仕”的范式演进
  • 从 JEPA 演进到 WAM:LeWorldModel 与 Fast-WAM 的一条连续技术脉络
  • 企业级AI Agent标准测评:从可靠性到场景适配的硬核评估指南
  • CLI命令行界面:从基础原理到高效开发与运维实践
  • 解决Redis局域网内不能访问的问题(Windows/Linux/虚拟机)
  • Win10/Win11系统Pads安装与卡死问题终极解决指南
  • LLM-Agent如何重塑信息不对称市场:博弈、挑战与多智能体模拟
  • AI Agent安全治理:基于执行边界与证据链的动态防护体系
  • Python标准库:被低估的原生基建与工程实践指南
  • S7-1500用户程序实现硬件IO自由组态
  • Spring Batch批处理核心原理:Chunk机制、重启策略与资源隔离
  • 技术博文生成规范与内容安全准则
  • Linux虚拟机实战避坑指南:从VMware安装到SSH终端调优
  • C++ 第k个最小元素(K’th Smallest Element)
  • 宝塔面板实战指南:从零搭建服务器运维图形化管理平台
  • 基于QtPy (PySide6) 的PLC-HMI工程实战记录(二)复制和应用PLC模板
  • 斯坦福EE364B凸优化II课程:从次梯度方法到模型预测控制的实践指南
  • ASP项目实战:从环境搭建到功能测试的完整指南
  • ASP动态界面开发:游戏化拖拽布局与数据持久化实战
  • 实力加冕!广州合优网络斩获 2022 年度网易外贸通市场开拓先锋奖
  • 故障注入测试(FIT)在汽车控制器开发中的专业实践:从ISO 26262到HIL工程落地
  • 导师反复要求补图?用AI把毕业设计逻辑整理成清晰结构
  • 健身预约类毕业设计:内容匹配+协同过滤的混合推荐怎么设计权重
  • Go GOMAXPROCS:cgroup与CPU配额管理
  • 从 MyContext 看 AI 办公 Agent 的上下文基建(local-first / 知识图谱 / 冲突处理)
  • 从 RAP 服务到 Business Role,彻底理解 SAP BTP ABAP environment 里的 IAM Application
  • webrtc-rs/webrtc v0.20.3更新:Android 网络切换后 ICE Restart 卡死约 10 秒的问题终于解决
  • (十四)IP-MAC 绑定配置命令五厂商对照:华为 华三 锐捷 迈普 思科
  • 2026年7月泰安市新房价格深度分析报告