拦截路由(Intercepting Routes)
@link: https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes
概念 拦截路由允许在当前布局中加载应用程序其他部分的路由,即在不切换用户上下文的情况下显示路由内容。例如,在信息流中点击照片时,可以在模态框中显示照片,覆盖信息流,此时 Next.js 拦截 /photo/123 路由,掩盖 URL 并覆盖在 /feed 上。
路由约定(路由文件夹结构) 以特定的文件夹结构来组织拦截路由相关的代码。
使用 (..) 约定来定义拦截路由,类似于相对路径约定 ../ 但用于路由段。
(.) 匹配同一级别的段,(..) 匹配上一级别的段,(..)(..) 匹配上两级别的段,(...) 匹配从根应用目录开始的段。 例如,可通过创建 (..)photo 目录从 feed 段中拦截 photo 段。 注:该约定基于路由段而非文件系统。
注意导航方式
软导航 通过点击信息流中的照片等客户端导航方式,在模态框中显示内容,此时进行路由拦截。硬导航 通过点击可分享 URL 或刷新页面导航到照片时,应渲染整个照片页面,不进行路由拦截。
实践中认识
直观效果: 可以参见“花瓣网”的图片列表->图片详情的样式与路由变化 下面简单仿制花瓣网界面布局用于认识NextJS的拦截路由(Intercepting Routes)
准备环境
react: ^18next: 14.2.20tailwindcss: ^3.4.1typescript: ^5
页面样式跳过,文末有完整项目代码
目录结构
app目录下目录结构准备
代码
效果表现
步骤:
从列表随机选择一个进入详情页此时详情页的路由地址被打开 (注: 此时样式类似Modal 对话框的表现形式,层叠在原有列表页面上)当重新刷新页面时,似乎进到了“全新的页面”上
这种表现形式,在Next.js框架中称为拦截路由(Intercepting Routes)
重点部分
在上面目录结构上,是否好奇search目录下的@modal、(..)pins这类奇奇怪怪的目录名称?下面重点解释解释
@modal命名粗暴理解的话也可以当作是路由组的另一种表达形式(规则:@ + [name] 命名) 也就是《Parallel Routes:Tab Groups》,并行路由里提到的标签组的概念;
(..)pins命名就是拦截路由的关键了,这里表达的是:
在上游是/search路由下访问/pins/[id]路由的拦截和指向而pins目录和search是同级的,则../pins就可以找到(类似文件系统里的相对路径)注:@[name]规则的目录是被忽略的层级, 并且拦截路径要和目标路由路径保持一致(例:(..)pins/[id]与pins/[id])
除了上面两部分特殊命名外,还需要default.tsx和layout.tsx的辅助,才能最终完成整体的效果;
default.tsx部分
并行路由:default.js文件约定:default.js
layout.tsx部分
在要进行拦截的路由下建立(就像上面的/search路由下要拦截/pins/[id]这种情景下);
建立layout文件的目的是为了拦截路由后的呈现(为目标路由内容呈现预留“插槽”位置)
// file: app/(root)/search/layout.tsx
import type {ReactNode} from "react";
const PageLayout = function (props: Readonly<{
children: ReactNode,
modal: ReactNode
}>) {
const {children, modal} = props;
return (
<>
{children}
{modal}
>
)
}
export default PageLayout;
至此几个要点部分应该都说到了,有啥不足评论区里一起探讨探讨!
完整代码可移步到《GitCode: demo-Intercepting-routes》项目上