nextjs中,关于Layout组件和Page组件的认知

一、Layout------页面的布局结构

当用户访问next项目中的一个页面,如果这个页面的路由对应文件夹下面有layout.tsx,那么next就会基于这个文件里面的dom结构,渲染当前页面结构。Layout的通常传参非常简单,因为它负责的仅仅只有负责当前页面的布局这一项工作。

tsx 复制代码
// 一般路由文件夹下的layout.tsx只需要渲染children即可
interface LayoutProps {
    children: React.ReactNode 
}

export default function Layout({ children }: LayoutProps) {
  return <div className="min-h-screen w-full">{children}</div>
}
tsx 复制代码
// app顶层文件夹的layout除了children,还需要渲染html和body
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

通常当用户访问页面路由,next会先匹配对应文件夹下面的page.tsx,然后再"自下而上"寻找Layout.tsx。

例如用户访问/blog这个页面的时候,会先寻找静态路由对应的文件夹blog,匹配到app/blog/page.tsx之后,如果当前文件夹中没有layout,那就逐级往上寻找layout,直到匹配到app/layout.tsx

plaintext 复制代码
app/
 ├── (marketing)/  --> 带括号,是路由组,继续往下找
 │    └── page.tsx --> 对应路径 "/"
 │
 ├── blog/  --> 对应路径 "/blog"
 │    └── page.tsx --> 找到目标,但是当前文件夹里面没有layout.tsx
 │
 └── Layout.tsx  --> 如果blog上级文件夹中有layout.tsx,那就用这个layout.tsx来渲染blog/page.tsx

二、Page------页面的业务内容

Layout.tsx负责当前页面的结构,通常里面的代码都是没有复杂业务逻辑的静态纯组件,承担业务逻辑的都是Page.tsx。

Page有params和searchParams两个默认参数。params用于获取 动态路由 (Dynamic Routes)中的参数。例如,如果你的文件路径是 app/blog/[slug]/page.tsx,那么 params 就会包含 slugsearchParams用于获取 URL 中 问号后面的查询参数 (Query Parameters)。例如 ?query=nextjs&page=1

tsx 复制代码
const Page = async({
    params,
    searchParams
}:{
    params:Promise<{slug:string}>, 
    searchParams:Promise<{[key: string]:string | string[] | undefined}>
}) =>{
    const {slug} = await params;
    const urlParams = await searchParams;
    console.log(slug, urlParams);
    return <>
        <Nav />
        <p>Hello, I'm the blog page</p>
    </>
}
export default Page

当访问/blog/a?query=11111&query=222222&b=5时,console会输出: 其中['a']是只有访问动态路由才会有输出,如果访问一个静态路由地址,params输出就是undefined,searchParams则会以键值对的形式展示出来

三、路由组划分多根模板

nextjs通过(folder)的方式划分路由组,路由组本身并不会被next识别为路由,比如文件结构如果是/app/(marketing)/blog/page.tsx,那么只需要访问/blog就能访问到这个page.tsx。

路由组虽然不会被识别为路由,但由于上面提到的page"从内而外"匹配layout渲染的机制,不同的模块都可以有自己的rootlayout:

plaintext 复制代码
app/
 ├── (marketing)/  --> marketing模块对应路由组
 │    └── page.tsx --> 对应路径 "/"
 |    └── layout.tsx --> marketing模块下所有page的根layout 
 |
 ├── (dashboard)/  --> 
 │    └── dashboard/
 │         └── page.tsx --> 对应路径 "/dashboard"
 │         └── layout.tsx --> dashboard模块下所有page的根layout
相关推荐
徐小夕10 分钟前
JitWord Office预览引擎:如何用Vue3+Node.js打造丝滑的PDF/Excel/PPT嵌入方案
前端·vue.js·github
晴殇i19 分钟前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
孟陬39 分钟前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
BER_c39 分钟前
前端权限校验最佳实践:一个健壮的柯里化工具函数
前端·javascript
兆子龙43 分钟前
别再用 useState / data 管 Tabs 的 activeKey 了:和 URL 绑定才香
前端·架构
sudo_jin43 分钟前
前端包管理器演进史:为什么 npm 之后,Yarn 和 pnpm 成了新宠?
前端·npm
叁两2 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
golang学习记2 小时前
GitLens 十大神技:彻底改变你在 VS Code 中的 Git 工作流
前端·后端·visual studio code
SuperEugene2 小时前
后台权限与菜单渲染:基于路由和后端返回的几种实现方式
前端·javascript·vue.js
兆子龙2 小时前
WebSocket 入门:是什么、有什么用、脚本能帮你做什么
前端·架构