Next Route 导图
- 基于文件系统的路由:通过pages目录中的文件结构自动创建路由。添加到pages目录的文件即成为一个可访问的路由。
- 页面与布局:可以创建第一个页面和共享布局。分页路由器(Pages Router)能够帮助你快速实现。
- 动态路由:允许你在URLs中添加自定义参数。通过创建特殊的文件和文件夹命名,可以捕获URL中的数据。
- 链接与导航:通过Link组件以及useRouter钩子来实现客户端的导航和跳转。
- 重定向:学会在Next.js中处理重定向的不同方式。
- 自定义App组件:通过覆盖Next.js默认的App组件,可以控制页面初始化,并为所有页面添加持久的布局。
- 自定义文档:扩展Next.js添加的默认文档标记。
- API路由:支持在Next.js应用内建立API,无需另行部署服务器或服务。
- 自定义错误处理:可以覆盖并扩展内建的错误页面,以处理自定义错误。
- 国际化:Next.js内置了对国际化路由和语言检测的支持。
- 中间件:学习如何使用中间件来在请求完成前运行代码。
Next Route 基础知识
自动路由映射
Next.js通过pages目录中的文件结构自动创建路由。例如,如果你在pages目录下创建了about.js,那么Next.js会自动将/about这个URL路由到这个文件对应的组件。
动态路由
Next.js支持通过文件名来创建动态路由。如果一个页面的文件名用方括号括起来,如[param].js,则表示这部分的URL是动态的,可以匹配任何值,并且这个值可以在页面组件内部通过useRouter钩子或getServerSideProps、getStaticProps等函数作为参数获取。
嵌套路由:
在有层级结构的页面中,可以通过创建嵌套文件夹来实现。例如,你想要创建一个/products/shoes的路由,你可以在pages目录下创建一个叫products的文件夹,然后在该文件夹中创建shoes.js文件。
链接与导航
在Next.js中,可以使用Link组件来创建客户端的路由跳转,这样可以实现页面的无刷新加载。Link组件避免了浏览器默认的全页刷新行为。
服务器端渲染和静态生成
Next.js支持两种预渲染形式—静态生成和服务器渲染。使用静态生成的页面在构建时生成并可重复使用,在服务器渲染中,每个请求都会渲染页面。
404
Next.js自动提供了一个404错误页面,当路由不匹配任何页面或文件时显示。开发者也可以自定义404页面,以匹配网站的整体风格。
路由守卫和中间件:
Next.js支持中间件,可以用来处理请求并在继续路由处理前运行一些代码,比如验证用户身份或日志记录。
路由目录
app目录
在Next.js的新版本中(从13版开始),引入了名为app的新目录。这个目录是为了容纳Next.js引入的新特性,如App Router,它支持共享布局、嵌套路由、加载状态和错误处理等。
pages目录
pages目录是Next.js中传统的路由机制,每个文件对应一个路由。系统会根据文件结构自动创建路由。例如,pages/about.js会对应/about这个URL路径。
注意
- _App Router 优先于 Pages Router。_跨目录的路由不应解析为相同的 URL 路径,并且会导致生成时错误以防止冲突。
- 默契情况下,内部组件是app 是 React 服务器组件. 官方解释这种是性能优化,不过也可以使用客户端组件。
页面和Layout
页面
页面是通过创建page.js
来实现UI视图,例如你想创建一个 这样的访问URL http://localhost:3000/person
访问,那么需要再app
文件夹目录下新建文件夹person
,然后在创建page.tsx
即可。
注意
<font style="color:#000000;">.js</font>
、<font style="color:#000000;">.jsx</font>
或<font style="color:#000000;">.tsx</font>
文件扩展名可用于 Pages。- 默认情况下,页面是服务器组件,但可以设置为客户端组件.
布局Layout
布局是在多个路由之间共享的 UI。在导航时,布局会保留状态,保持交互性,并且不会重新呈现。布局也可以嵌套.
根布局
根布局在<font style="color:#000000;">app</font>
目录并应用于所有路由。此布局是必需的,并且必须包含<font style="color:#000000;">html</font>
和<font style="color:#000000;">body</font>
标记,允许您修改从服务器返回的初始 HTML。
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
嵌套Layout
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
注意
<font style="color:#000000;">.js</font>
、<font style="color:#000000;">.jsx</font>
或<font style="color:#000000;">.tsx</font>
文件扩展名可用于布局。- 只有根布局可以包含
<font style="color:#000000;"><html></font>
和<font style="color:#000000;"><body></font>
标签。 - 当在同一文件夹中定义
<font style="color:#000000;">layout.js</font>
和<font style="color:#000000;">page.js</font>
文件时,布局将包裹页面。 - 默认情况下,布局是服务器组件,但可以设置为客户端组件.
- 布局无法访问其下方的路由段。要访问所有路由段,您可以使用useSelectedLayoutSegment或useSelectedLayoutSegments在客户端组件中。
模板 template
元数据
可以修改<font style="color:#000000;"><head></font>
HTML 元素。
通过导出metadata对象或generateMetadata功能在一个layout.js或page.js文件。
import type { Metadata } from "next";
// 配置页面的元数据
export const metadata: Metadata = {
// 页面标题
title: "海军",
// 页面描述
description: "这是页面的描述信息,通常会出现在搜索引擎结果中。",
// 关键词
keywords: "工具网站, 关键词2, 关键词3",
// Viewport 设置,用于响应式设计
viewport: "width=device-width, initial-scale=1.0",
// Open Graph 协议,用于社交分享
openGraph: {
title: "海军 - 网站名称",
description: "这是页面的描述信息,通常会出现在搜索引擎结果中。",
images: "/path/to/image.jpg",
url: "https://www.example.com/page-url",
type: "website",
},
// Twitter 卡片设置
twitter: {
card: "summary_large_image",
title: "海军 - 网站名称",
description: "这是页面的描述信息,通常会出现在搜索引擎结果中。",
images: "/path/to/image.jpg",
},
};
路由链接和导航
Link 组件
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
}
usePathname 钩子 检查激活的链接
'use client'
import { usePathname } from 'next/navigation'
import Link from 'next/link'
export function Links() {
const pathname = usePathname()
return (
<nav>
<ul>
<li>
<Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
Home
</Link>
</li>
<li>
<Link
className={`link ${pathname === '/about' ? 'active' : ''}`}
href="/about"
>
About
</Link>
</li>
</ul>
</nav>
)
}
useRouter 钩子
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
redirect 重定向
import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }: { params: { id: string } }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
最后
文章分享就到此结束了,如果大家觉得文章不错的话,可以关注我:程序员海军,后续还会分享更多Web最新最全的动态。