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
相关推荐
এ慕ོ冬℘゜43 分钟前
前端实战:jQuery实现动态表格渲染与状态切换功能
前端·javascript·jquery
zzzzzz3101 小时前
react-bits:把酷炫动效从“灵感截图”变成可复用的 React 组件
javascript·react.js·动效
jay神2 小时前
【计算机毕业设计】基于Flask+Vue的电影数据可视化与智能推荐系统
前端·vue.js·python·信息可视化·flask·毕业设计·课程设计
FreeTinker8 小时前
HTML本地存储技术解析:localStorage与sessionStorage的原理、差异与应用场景
前端·html
qq_452396238 小时前
第十二篇:《全链路监控与可观测性:前端错误追踪与性能分析》
前端
wangruofeng9 小时前
Phosphor Icons 官网源码拆解:URL 即存储、水波动画与 7362 Star 图标库的架构实践
前端·架构·github
BigTopOne9 小时前
WebRTC Native / Android 开发学习资源整理
前端
excel10 小时前
nuxt 3 升级 nuxt 4 报错之 hasInjectionContext
前端
何以解忧,唯有..10 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain