NextJs 路由管理

发布于:2024-12-18 ⋅ 阅读:(15) ⋅ 点赞:(0)

NextJs 路由管理

Defining Routes

1. Creating Routes

在这里插入图片描述

在这里插入图片描述

2. Creating UI

export default function Page() {
  return <h1>Hello, Next.js!</h1>
}

Route Groups 路由组

1. 在不影响 URL 路径的情况下组织路由

要在不影响 URL 的情况下组织路由,请创建一个组以将相关路由放在一起。括号中的文件夹将从 URL 中省略(例如 (marketing)(shop))。
在这里插入图片描述

2. 为分组创建不同的布局

即使 (marketing)(shop) 内部的路由共享相同的 URL 层次结构,您也可以通过在组的文件夹中添加 layout.js 文件来为每个组创建不同的布局。

在这里插入图片描述

3. 为分组加载骨架

要通过 loading.js 文件将加载骨架应用于特定路由,请创建一个新的路由组(例如,/(overview)),然后将 loading.tsx 移动到该路由组内。

在这里插入图片描述

4. 创建多个根布局

要创建多个根布局,请删除顶级 layout.js 文件,并在每个路由组内添加一个 layout.js 文件。这对于将应用程序划分为具有完全不同 UI 或体验的部分非常有用。需要将 <html><body> 标记添加到每个根布局中。 示例中,(marketing)(shop) 都有自己的根布局。
在这里插入图片描述

注:

包含路由组的路由不应解析为与其他路由相同的 URL 路径。例如,由于路由组不会影响 URL 结构,因此 (marketing)/about/page.js(shop)/about/page.js 都会解析为 /about 并导致错误。

Dynamic Routes 并行路由

1. Convention

可以通过将文件夹名称括在方括号中来创建动态区段:[folderName]。例如,[id][slug]。

动态 Segments 作为 params 属性传递给 layoutpageroutegenerateMetadata 函数。

例如,博客可以包含以下路由 app/blog/[slug]/page.js其中 [slug] 是博客文章的动态区段。

文件 app/blog/[slug]/page.tsx

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const slug = (await params).slug
  return <div>My Post: {slug}</div>
}
Route Example URL params
app/blog/[slug]/page.js /blog/a { slug: 'a' }
app/blog/[slug]/page.js /blog/b { slug: 'b' }
app/blog/[slug]/page.js /blog/c { slug: 'c' }

2. Catch-all Segments

动态区段可以通过在方括号内添加省略号 [...folderName]

Route Example URL params
app/shop/[...slug]/page.js /shop/a { slug: ['a'] }
app/shop/[...slug]/page.js /shop/a/b { slug: ['a', 'b'] }
app/shop/[...slug]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }

3. Optional Catch-all Segments

可以通过在双方括号中包含参数来使 catch-all Segments 成为可选的[[...folderName]]

Route Example URL params
app/shop/[[...slug]]/page.js /shop { slug: undefined }
app/shop/[[...slug]]/page.js /shop/a { slug: ['a'] }
app/shop/[[...slug]]/page.js /shop/a/b { slug: ['a', 'b'] }
app/shop/[[...slug]]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }

catch-alloptional catch-all 段之间的区别在于,使用 optional 时,也会匹配不带参数的路由(上例中为 /shop)。

TypeScript

app/blog/[slug]/page.tsx

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  return <h1>My Page</h1>
}
Route params Type Definition
app/blog/[slug]/page.js { slug: string }
app/shop/[...slug]/page.js { slug: string[] }
app/shop/[[...slug]]/page.js { slug?: string[] }
app/[categoryId]/[itemId]/page.js { categoryId: string, itemId: string }

Parallel Routes 并行路由

1. Parallel Routes

Parallel Routes 允许您同时或有条件地呈现同一布局中的一个或多个页面。它们对于应用程序的高度动态部分非常有用,例如社交网站上的仪表板和源。

例如,考虑一个仪表板,您可以使用并行路由同时呈现团队 和分析 页面:

在这里插入图片描述

2. Slot

并行路由是使用命名创建的。插槽是使用 @folder 约定定义的。例如,以下文件结构定义了两个插槽:@analytics@team

在这里插入图片描述

插槽作为 props 传递给共享的父布局。在上面的例子中,app/layout.js 中的组件现在接受 @analytics@team 插槽 props,并且可以与 children 属性一起并行渲染它们:

export default function Layout({
  children,
  team,
  analytics,
}: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {children}
      {team}
      {analytics}
    </>
  )
}

在这里插入图片描述

import { checkUserRole } from '@/lib/auth'
 
export default function Layout({
  user,
  admin,
}: {
  user: React.ReactNode
  admin: React.ReactNode
}) {
  const role = checkUserRole()
  return <>{role === 'admin' ? admin : user}</>
}

不是路由段,不会影响 URL 结构。例如,对于 /@analytics/views,URL 将为 /views,因为 @analytics 是一个槽。插槽与常规 [Page]组件组合在一起,以形成与路由段关联的最终页面。因此,您不能在同一路由分段级别拥有单独的[静态]和[动态]插槽。如果一个槽是动态的,则该级别的所有槽都必须是动态的。