拦截路由
允许从当前布局中应用程序的其他部分加载路由,且只显示路由的内容,而不让用户切换到其他地方。 可以通过创建目录从区段中拦截区段,来进行路由拦截。
(.)匹配同一级别的区段(..)匹配上一级的区段(..)(..)匹配上两级的区段(...)匹配根目录中的段app
注意:匹配哪一级的区段是按照路由的嵌套来选择的,不是按照文件夹的嵌套来选择的
案例
实现一个图片列表,单击信息源中的图片时,可以在模态视图中显示该图片的大图,并叠加信息源,通过分享所点击的图片地址,可以直接从分享的URL导航到图片的详细页面。
实现过程如下: 先创建一个图片列表和数据信息,实现点击跳转的功能
// app/page.tsx
import React from 'react'
import { photos } from '@/data'
import Image from 'next/image'
import Link from 'next/link'
export default function page() {
return (
Products
{photos.map((item) => (
href={`/photos/${item.id}`}
className="group"
key={item.id}
>
className="w-full h-full object-cover " src={item.src} width={200} height={200} alt={item.alt} />
{item.alt}
${item.price}
))}
)
}
// data.ts
export const photos = [
{
id: '1',
src: 'https://q4.itc.cn/q_70/images03/20240319/c0e2ec2d2bc44d299d6bdf53f38298ed.png',
alt: 'one photo',
price: 100,
},
{
id: '2',
src: 'https://q4.itc.cn/q_70/images03/20240319/45b821c43c844bfda1b7e573b6fa6e8f.png',
alt: 'two photo',
price: 100,
},
{
id: '3',
src: 'https://q4.itc.cn/q_70/images03/20240319/b2cdde93536c44bbba5c6170f92f25a8.png',
alt: 'three photo',
price: 100,
},
{
id: '4',
src: 'https://q4.itc.cn/q_70/images03/20240319/5567d75589bd46439af8e835beeac44f.png',
alt: 'four photo',
price: 100,
},
]
为跳转成功后,打开的新页面创建页面布局(硬导航)
import React from 'react'
import Image from 'next/image'
import { photos } from '@/data'
export default function page({ params }: { params: { id: string } }) {
const photo = photos.find((p) => p.id === params.id)!
return (
src={photo.src} width={300} height={300} className="rounded-lg block mx-auto" alt={photo.alt} /> Title: {photo.alt} Price: {photo.price} Description: 这是一段描述
)
}
在点击图片时要实现一个遮罩层和路由的跳转,同时页面不可以进行跳转,需要用到路由拦截
'use client'
import React, { useState, useEffect } from 'react'
import Image from 'next/image'
import { photos } from '@/data'
import { useParams, useRouter } from 'next/navigation'
export default function page() {
const params = useParams<{ id: string }>()
const photo = photos.find((p) => p.id === params.id)!
const router = useRouter()
return (
className="flex justify-center items-center fixed inset-0 bg-gray-500/[.8]"
onClick={router.back}
>
src={photo?.src} width={300} height={300} className="rounded-lg" alt={photo?.alt} onClick={(e) => e.stopPropagation()} />
)
}
注意:Next.js 15之后的版本可能会遇到直接访问的参数的错误,需要进行参数的处理 客户端组件,使用钩子 useParams 服务器组件,只需使组件异步并等待参数
在使用并行路由时,default文件可以直接设置为空,但是不能没有这个文件来呈现不匹配的槽时的回退
import React from 'react'
export default function page() {
return null
}
使用并行路由时,也需要在app文件夹下的layout文件中进行设置
export default function RootLayout({
children,
modal,
}: Readonly<{
children: React.ReactNode
modal: React.ReactNode
}>) {
return (
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
{modal}
)
}
由此可以实现此案例。