第 4 章:页面组件与布局系统
4.1 页面布局的几种方式
Next.js 支持灵活的页面布局方式,常见有两种:
✅ 单一全局布局(所有页面使用同一套布局)
适合统一的页面结构,如固定的导航栏、侧边栏、页脚等。
✅ 每页自定义布局(某些页面有不同的结构)
适合后台系统、多主题平台、特殊页面(如登录页)等。
4.2 自定义 App 入口(_app.js)
pages/_app.js 是每个页面的顶层组件,可以在这里引入全局样式、添加 Layout、初始化状态管理(如 Redux、Context)等。
示例一:引入全局样式 + 通用布局
// pages/_app.js
import '@/styles/globals.css';
import Layout from '@/components/Layout';
export default function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
✅ 作用类似 React 的根节点
<App />,每个页面都会走过这里。
4.3 创建 Layout 组件
示例:components/Layout.js
import Link from 'next/link';
export default function Layout({ children }) {
return (
<>
<header>
<nav>
<Link href="/">首页</Link> | <Link href="/about">关于</Link>
</nav>
</header>
<main>{children}</main>
<footer>© 2025 Eric Blog</footer>
</>
);
}
4.4 支持每页自定义布局(可选)
有些页面不需要通用布局,比如登录页。可以在页面组件里定义 getLayout 方法。
示例:
// pages/login.js
export default function LoginPage() {
return <div>这是登录页</div>;
}
LoginPage.getLayout = function PageLayout(page) {
return (
<div className="login-wrapper">
<h1>请登录</h1>
{page}
</div>
);
};
修改 _app.js:
export default function MyApp({ Component, pageProps }) {
const getLayout = Component.getLayout || ((page) => page);
return getLayout(<Component {...pageProps} />);
}
✅ 如果没有定义
getLayout,就使用默认渲染;如果定义了,就用该页面的个性化布局。
4.5 自定义 HTML 模板结构(_document.js)
_document.js 用于定制最外层 HTML 页面结构,比如 <html>、<head>、自定义字体、Meta 信息等。
// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document';
export default function Document() {
return (
<Html lang="zh">
<Head>
<link rel="icon" href="/favicon.ico" />
<meta name="description" content="Eric 的 Next.js 博客" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
注意:
_document.js只能在服务端运行,不能添加事件监听或运行浏览器 JS。
4.6 样式支持方式总结
Next.js 支持多种 CSS 写法:
| 方式 | 特点 | 推荐使用场景 |
|---|---|---|
| CSS Modules | 默认支持,作用域隔离 | 中小项目,组件局部样式 |
| 全局 CSS | 在 _app.js 引入 | 公共样式(reset、字体) |
| Sass / Less | 需安装依赖 | 样式更复杂时使用 |
| Tailwind CSS | 原子化 CSS 框架 | 中大型项目,灵活高效 |
| styled-components | CSS-in-JS | 搭配 React 灵活控制 |
示例:使用 CSS Module(推荐)
/* styles/Home.module.css */
.title {
color: blue;
font-size: 2rem;
}
// pages/index.js
import styles from '@/styles/Home.module.css';
export default function Home() {
return <h1 className={styles.title}>欢迎来到我的 Next.js 博客</h1>;
}
✅ 小结
| 功能 | 文件 | 说明 |
|---|---|---|
| 全局布局 | pages/_app.js | 页面初始化、状态管理、全局 CSS、布局封装 |
| HTML 模板 | pages/_document.js | 自定义 <html>、<head>、字体、meta 标签等 |
| 通用组件 | components/Layout.js | 封装导航、footer 等 |
| 每页布局 | Page.getLayout() | 灵活定义每页结构(适合后台系统) |
| 样式方案 | CSS Modules / Tailwind / styled-components | 按需选择 |