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

Web典型路由结构之Next.js (App Router, v13+) )(文件系统驱动的路由:File-based Routing)声明式路由:文件即路由

文章目录

  • 📂 项目结构 (基于 `app` 目录)
  • 🔑 核心文件实现
    • 1. 根布局 (`app/layout.tsx`)
    • 2. 首页 (`app/page.tsx`)
    • 3. 项目列表页 (`app/projects/page.tsx`)
    • 4. 项目详情页 (`app/projects/[projectId]/page.tsx`)
    • 5. 设置页权限控制 (`app/settings/layout.tsx`)
    • 6. 登录页 (`app/signin/page.tsx`)
    • 7. 404 页面 (`app/not-found.tsx`)
    • 8. 错误处理 (`app/error.tsx`)
  • 🌟 与 React Router v6 的关键差异
  • ✅ 为什么 Next.js 的设计更优?
    • 1. **无需维护路由配置**:文件系统即路由,新增页面只需创建文件
    • 2. **自动代码分割**:按路由自动分割代码块(无需 `lazy`)
    • 3. **权限控制更合理**:在布局层处理(避免页面加载后再重定向)
    • 4. **开发体验更好**:文件命名即路由,直观易维护
    • 5. **内置 404/错误处理**:`not-found.tsx` 和 `error.tsx` 自动生效
    • > 💡 提示:Next.js 的权限控制**不要**在 `page.tsx` 中做(会先加载页面再重定向),必须放在 `layout.tsx` 中(如 `settings/layout.tsx`)。
  • 🚀 运行效果
  • > ✨ **关键总结**:Next.js 的路由是**声明式**的(文件即路由),而 React Router 是**配置式**的(需要手动写路由表)。Next.js 的设计让路由与文件结构绑定,大幅降低维护成本,同时内置了最佳实践(权限、404、动态路由)。

以下是 Next.js (App Router, v13+) ( SSR)的典型路由结构实现,与 React Router v6( CSR) 的配置式路由不同,Next.js 采用 文件系统驱动的路由(File-based Routing),无需显式编写路由配置文件:


📂 项目结构 (基于 app 目录)

app/
├── layout.tsx             # 根布局 (所有页面共享)
├── page.tsx               # 根路径 / 的页面
├── projects/
│   ├── layout.tsx         # 项目模块布局
│   ├── page.tsx           # /projects 页面
│   └── [projectId]/       # 动态路由
│       └── page.tsx       # /projects/:projectId
├── settings/
│   ├── layout.tsx         # 设置页布局 (用于权限控制)
│   └── page.tsx           # /settings 页面
├── signin/
│   └── page.tsx           # /signin 页面
├── not-found.tsx          # 404 页面 (自定义)
└── error.tsx              # 全局错误页面

🔑 核心文件实现

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

// app/layout.tsx
// 导入全局CSS样式文件(在Next.js中,全局样式通常放在这里)
import './globals.css'
// 导入Google字体(Inter字体),用于设置页面的字体
import { Inter } from 'next/font/google'// 使用Inter字体,指定子集为拉丁文(支持大部分英文字符)
const inter = Inter({ subsets: ['latin'] })// 设置页面的元数据(标题、描述等,用于SEO优化)
export const metadata = {title: 'Next.js App', // 页面标题description: 'Generated by Next.js', // 页面描述
}// 根布局组件,所有页面共享这个布局
export default function RootLayout({children,
}: {children: React.ReactNode // 代表子组件(页面内容)
}) {// 返回HTML结构,其中包含页面的根元素return (<html lang="en"> // 指定页面语言为英语<body className={inter.className}> // 将字体类名应用到body,使页面使用Inter字体<header>My App Header</header> // 页面头部(通常包含导航栏){children} // 这里是子组件(当前页面的内容)将被渲染在这里<footer>Footer</footer> // 页面底部</body></html>)
}

2. 首页 (app/page.tsx)

// app/page.tsx
// 首页组件,处理根路径 / 的页面内容
export default function Home() {// 返回页面的主要内容return (<main> // 主要内容区域<h1>Welcome to Home</h1> // 标题<a href="/projects">Go to Projects</a> // 链接到项目列表页的链接</main>)
}

3. 项目列表页 (app/projects/page.tsx)

// app/projects/page.tsx
// 项目列表页面组件
export default function Projects() {// 返回项目列表页面的内容return (<div> // 容器div<h1>Projects List</h1> // 项目列表标题<ul> // 无序列表<li><a href="/projects/1">Project 1</a></li> // 项目1的链接<li><a href="/projects/2">Project 2</a></li> // 项目2的链接</ul></div>)
}

4. 项目详情页 (app/projects/[projectId]/page.tsx)

// app/projects/[projectId]/page.tsx
// 项目详情页面组件,用于显示特定项目的详细信息
import { notFound } from 'next/navigation' // 用于触发404页面的函数// 项目详情页面组件,接收参数(动态路由参数)
export default function ProjectDetail({ params }: { params: { projectId: string } }) {// 模拟项目数据(实际应用中会从API获取)const validProjects = ['1', '2', '3']// 检查传入的projectId是否有效if (!validProjects.includes(params.projectId)) {notFound() // 如果无效,触发404页面}// 返回项目详情页面return (<div> // 容器div<h1>Project Detail: {params.projectId}</h1> // 显示项目ID<a href="/projects">Back to Projects</a> // 返回项目列表的链接</div>)
}

5. 设置页权限控制 (app/settings/layout.tsx)

关键点:权限检查放在布局层(避免页面加载后再重定向)

// app/settings/layout.tsx
import { cookies } from 'next/headers' // 用于操作HTTP cookies
import { redirect } from 'next/navigation' // 用于重定向页面// 设置页布局组件,用于权限控制
export default function SettingsLayout({children,
}: {children: React.ReactNode // 代表子组件(设置页面内容)
}) {// 从cookies中获取token(用于用户认证)const token = cookies().get('token')?.value// 如果没有token(用户未登录),重定向到登录页// encodeURIComponent确保URL安全if (!token) {redirect(`/signin?next=${encodeURIComponent('/settings')}`)}// 如果有token,渲染设置页面内容return (<div><h2>Settings</h2> // 设置页面标题{children} // 渲染子组件(实际的设置内容)</div>)
}

6. 登录页 (app/signin/page.tsx)

// app/signin/page.tsx
import { cookies } from 'next/headers' // 用于操作HTTP cookies
import { redirect } from 'next/navigation' // 用于重定向页面// 登录页面组件
export default function SignIn() {// 模拟登录逻辑的函数const handleLogin = () => {// 设置cookie(存储token)cookies().set('token', 'dummy_token')// 从cookies中获取重定向路径(如果之前访问的是受保护页面)const next = cookies().get('next')?.value || '/'// 重定向到目标页面redirect(next)}return (<div><h1>Login</h1> // 登录页面标题<button onClick={handleLogin}>Sign In</button> // 登录按钮</div>)
}

7. 404 页面 (app/not-found.tsx)

// app/not-found.tsx
// 404页面组件(当请求的页面不存在时显示)
export default function NotFound() {return (<main> // 主要内容区域<h1>404 - Page Not Found</h1> // 404标题<a href="/">Go Home</a> // 返回首页的链接</main>)
}

8. 错误处理 (app/error.tsx)

// app/error.tsx
import { notFound } from 'next/navigation' // 用于触发404页面的函数// 错误处理页面组件
export default function Error() {return (<main> // 主要内容区域<h1>Something went wrong</h1> // 错误提示<button onClick={() => notFound()}>Go to 404</button> // 点击按钮跳转到404页面</main>)
}

🌟 与 React Router v6 的关键差异

特性React Router v6Next.js (App Router)
路由定义显式配置文件 (routes.tsx)文件系统自动映射 (app/ 目录)
布局通过 children 嵌套layout.tsx 文件 (自动继承)
权限控制高阶组件 (withAuth)layout.tsx 中直接重定向
动态路由:param 语法 (/projects/:id)[param] 语法 (/projects/[id])
404 页面* 通配符 + errorElementnot-found.tsx 文件
懒加载手动 lazy + Suspense自动按需加载 (无需配置)
重定向redirect 函数 (路由配置中)redirect 函数 (在 layout.tsx/page.tsx 中)

✅ 为什么 Next.js 的设计更优?

1. 无需维护路由配置:文件系统即路由,新增页面只需创建文件

2. 自动代码分割:按路由自动分割代码块(无需 lazy

3. 权限控制更合理:在布局层处理(避免页面加载后再重定向)

4. 开发体验更好:文件命名即路由,直观易维护

5. 内置 404/错误处理not-found.tsxerror.tsx 自动生效

> 💡 提示:Next.js 的权限控制不要page.tsx 中做(会先加载页面再重定向),必须放在 layout.tsx 中(如 settings/layout.tsx)。


🚀 运行效果

URL对应文件效果
/app/page.tsx首页
/projectsapp/projects/page.tsx项目列表
/projects/123app/projects/[projectId]/page.tsx项目详情 (动态参数)
/settingsapp/settings/layout.tsx + page.tsx受保护设置页 (需登录)
/signinapp/signin/page.tsx登录页
/non-existentapp/not-found.tsx自定义 404 页面

> ✨ 关键总结:Next.js 的路由是声明式的(文件即路由),而 React Router 是配置式的(需要手动写路由表)。Next.js 的设计让路由与文件结构绑定,大幅降低维护成本,同时内置了最佳实践(权限、404、动态路由)。

http://www.dtcms.com/a/422562.html

相关文章:

  • 【设计模式】解释器模式
  • 【前端知识】iframe 使用详细说明
  • 推荐一款集成AI功能的数据库管理工具
  • Flask 入门:轻量级 Python Web 框架的快速上手
  • 每日前端宝藏库 | tinykeys ✨
  • 第7章:TS快速入门和前端项目初始化
  • 合肥 做网站的深圳办公室装修设计公司
  • Android实现RecyclerView粘性头部效果,模拟微信账单列表的月份标题平移
  • 建三江建设局网站网站建设自我评价怎么写比较好
  • 华为Fit4手表:个性化表盘,让生活更有温度
  • Spring Boot - 从PF4J到SBP:深入解析Java插件化架构的演进与实践
  • 河南做网站企起做平面什么网站的素材不侵权
  • 哪个网站做ppt模板赚钱手机棋牌游戏平台
  • 鸿蒙app开发中 拿到json文件数据进行动画的播放
  • 第三章 鸽巢原理
  • 智慧政务——解读57页清华大学:DeepSeek政务场景应用与解决方案【附全文阅读】
  • Transformer模型:深度解析自然语言处理的革命性架构
  • 声网AI逐字拆解问题,30天重塑口语清晰表达
  • Java异常简介
  • VSCode Web版本安装
  • 实用软件 | 实时监控andriod设备硬件状态-devcheck
  • 非关系型数据库(NoSQL):特性、类型与应用指南​
  • 性能革命的底层逻辑:深入理解 Spring Cloud Gateway 的 Reactor 核心
  • 2025 年 AI+BI 趋势下,Wyn 商业智能软件如何重构企业决策效率?
  • 网站开发合同印花税公司网站建设重点内容
  • CMake cmake_parse_arguments
  • 4、存储系统架构 - 从机械到闪存的速度革命
  • 淘宝店铺全量商品接口深度开发:从分页优化到数据完整性保障
  • 视频MixformerV2 onnx导出
  • winfrom 的 BindingSource ,ist<T> + LINQ,DataTable + DataView 自动刷新机制 优势劣势