返回博客列表

NextJS 语法

2026-01-29
3 min read
nextjs

我帮你把内容排版和格式优化一下,让你的博客更清晰、易读,同时保留代码示例和说明: -- Next.js 中目录就是路由 在 Next.js 13+ 的 App Router 中,目录结构直接对应路由路径,因此命名非常重要。 :布局组件,用于包裹页面内容,可以在目录中继承。 :页面组件,对应具体路由。 目录结构示例 --- 路由对应关系 URL 路径 | 对应文件 ...

我帮你把内容排版和格式优化一下,让你的博客更清晰、易读,同时保留代码示例和说明:


Next.js 中目录就是路由

在 Next.js 13+ 的 App Router 中,目录结构直接对应路由路径,因此命名非常重要。

  • layout.tsx:布局组件,用于包裹页面内容,可以在目录中继承。
  • page.tsx:页面组件,对应具体路由。

目录结构示例

bash
➜ tree
└── app
    ├── blog
    │   ├── layout.tsx       # blog 下的布局
    │   ├── page.css         # blog 页面样式
    │   ├── page.tsx         # /blog 页面
    │   ├── post
    │   │   └── page.tsx     # /blog/post 页面
    │   └── posts
    │       └── [id]
    │           └── page.tsx # 动态路由 /blog/posts/:id 页面
    ├── favicon.ico
    ├── globals.css
    ├── layout.tsx           # 根布局
    └── page.tsx             # 根页面 /

路由对应关系

URL 路径对应文件
/app/page.tsx + app/layout.tsx
/blogapp/blog/page.tsx + app/blog/layout.tsx
/blog/postapp/blog/post/page.tsx + app/blog/layout.tsx
/blog/posts/123app/blog/posts/[id]/page.tsx + app/blog/layout.tsx

💡 小贴士

  • layout.tsx 可以多级嵌套,实现布局复用。
  • [id] 这样的文件夹表示 动态路由,可匹配任意参数。

好的,我帮你加一段 可视化路由树和布局继承关系图,用文本+箭头的方式表示,很适合博客展示:


Next.js 路由树与布局继承示意

app
├── layout.tsx        ← 根布局
├── page.tsx          ← / 根页面
└── blog
    ├── layout.tsx    ← /blog 专属布局(继承自根布局)
    ├── page.tsx      ← /blog 页面
    ├── post
    │   └── page.tsx  ← /blog/post 页面(继承 /blog/layout.tsx → 根布局)
    └── posts
        └── [id]
            └── page.tsx  ← /blog/posts/:id 页面(继承 /blog/layout.tsx → 根布局)

🔹 继承关系解释

  • 所有页面默认继承最近的上级 layout.tsx,如果没有则继承根布局。

  • /blog/post 的渲染顺序:

    根布局 app/layout.tsx
        ↓
    blog 布局 app/blog/layout.tsx
        ↓
    页面 app/blog/post/page.tsx
    
  • /blog/posts/123 的渲染顺序:

    根布局 app/layout.tsx
        ↓
    blog 布局 app/blog/layout.tsx
        ↓
    页面 app/blog/posts/[id]/page.tsx
    

💡 小结:

  • 文件夹结构 = 路由路径
  • layout.tsx = 层级继承布局
  • page.tsx = 页面内容

常用语法

同页面中用css

  • pm add @emotion/css
"use client";
import {css} from "@emotion/css";
const header = css`
    width: 100vw;
    display: flex;
    flex-direction: row;
    align-items: center;
    height: 100%;
`;

export default function BlogLayout({
                                       children,
                                   }: Readonly<{
    children: React.ReactNode;
}>){

  return (<><div className={header}></div></>)
}

定义layout

"use client";
import {Layout} from '@arco-design/web-react';
import "@arco-design/web-react/dist/css/arco.css";
import './page.css'
import React from "react";
import {Menu} from '@arco-design/web-react';
import {css} from "@emotion/css";

const MenuItem = Menu.Item;
const SubMenu = Menu.SubMenu;


const Sider = Layout.Sider;
const Header = Layout.Header;
const Footer = Layout.Footer;
const Content = Layout.Content;

const header = css`
    width: 100vw;
    display: flex;
    flex-direction: row;
    align-items: center;
    height: 100%;
`;

export default function BlogLayout({
                                       children,
                                   }: Readonly<{
    children: React.ReactNode;
}>) {
    return (<>
        <div className='layout-basic-demo'>
            <Layout className='h-screen'>
                <Header className='shadow-lg'>
                    <div className={header}>
                        <div className='flex-1'>
                        </div>
                        <div className='flex-2'>
                            <Menu mode='horizontal' defaultSelectedKeys={['1']}>
                                <MenuItem key='1'>Home</MenuItem>
                                <MenuItem key='2'>Solution</MenuItem>
                                <MenuItem key='3'>Cloud Service</MenuItem>
                                <MenuItem key='4'>Cooperation</MenuItem>
                            </Menu>
                        </div>
                    </div>

                </Header>
                <Content>
                    {children}
                </Content>
                <Footer>Footer</Footer>
            </Layout>
        </div>
    </>)
}


如何使用动态参数

注意目录要用 [id]

tsx
"use client";
import React from "react";
import {useParams} from "next/navigation";

export default function Post() {
    const params = useParams();
    const id = params?.id;

    if (!id) {
        return <h1 style={{textAlign: "center", color: "red"}}>未找到</h1>;
    }

    return <h1 style={{textAlign: "center", color: "black"}}>ID: {id}</h1>;
}

返回博客列表
最后更新于 2026-01-29
想法或问题?在 GitHub Issue 下方参与讨论
去评论