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
相关推荐
咩咩啃树皮7 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny8 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹8 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
阳光是sunny8 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
小林ixn8 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker9 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜9 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康9 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
一点一木10 小时前
从60首歌到1个网站:输入你的故事,还你一首歌
前端·github
IT_陈寒11 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端