Next.js 组件与布局
在 React 和 Next.js 中,组件是构建用户界面的核心。通过将 UI 拆分为独立、可重用的部分,我们可以更高效地开发和维护复杂的应用程序。本章将探讨如何在 Next.js 中组织组件,并创建适用于多个页面的共享布局。
1. 组件基础
在 Next.js 中,组件的编写方式与在标准 React 项目中完全相同。通常,我们会将所有组件存放在项目根目录下的 components 文件夹中,以便于管理。
创建一个简单的组件
让我们创建一个简单的 Button 组件。
创建文件:
components/Button.js编写组件代码:
jsx// components/Button.js import styles from './Button.module.css'; export default function Button({ children, onClick }) { return ( <button className={styles.button} onClick={onClick}> {children} </button> ); }为组件添加样式 (可选):
components/Button.module.csscss.button { background-color: #0070f3; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 1rem; } .button:hover { background-color: #005bb5; }
在页面中使用组件
现在,你可以在任何页面中导入并使用这个 Button 组件。
// pages/index.js
import Button from '../components/Button';
export default function HomePage() {
const handleClick = () => {
alert('Button clicked!');
};
return (
<div>
<h1>Welcome to My App</h1>
<Button onClick={handleClick}>Click Me</Button>
</div>
);
}2. 页面布局 (Layouts)
在大多数网站中,多个页面会共享相同的结构,例如页眉 (Header)、页脚 (Footer) 和导航栏 (Navigation Bar)。在 Next.js 中,有几种方法可以实现这种共享布局。
方法 1:创建布局组件
最常见的方法是创建一个 Layout 组件,然后用它来包裹每个页面的内容。
创建
Layout组件:components/Layout.js这个组件通常包含页眉、页脚,并通过
childrenprop 来渲染页面内容。jsx// components/Layout.js import Head from 'next/head'; import Header from './Header'; import Footer from './Footer'; export default function Layout({ children, title = 'My Next.js App' }) { return ( <div> <Head> <title>{title}</title> <meta charSet="utf-8" /> <meta name="viewport" content="initial-scale=1.0, width=device-width" /> </Head> <Header /> <main>{children}</main> <Footer /> </div> ); }我们还需要创建
Header和Footer组件。components/Header.jsjsximport Link from 'next/link'; import styles from './Header.module.css'; export default function Header() { return ( <header className={styles.header}> <nav> <Link href="/">Home</Link> <Link href="/about">About</Link> <Link href="/contact">Contact</Link> </nav> </header> ); }components/Footer.jsjsximport styles from './Footer.module.css'; export default function Footer() { return ( <footer className={styles.footer}> <p>© {new Date().getFullYear()} My Awesome App. All rights reserved.</p> </footer> ); }在
_app.js中使用Layout组件为了让所有页面都使用这个布局,我们可以在
pages/_app.js中包裹Component。jsx// pages/_app.js import Layout from '../components/Layout'; import '../styles/globals.css'; function MyApp({ Component, pageProps }) { return ( <Layout> <Component {...pageProps} /> </Layout> ); } export default MyApp;通过这种方式,
Layout组件会自动应用于所有页面,而无需在每个页面文件中单独导入。
方法 2:每页布局 (Per-Page Layouts)
有时,你的应用中可能需要多种不同的布局(例如,一种用于主应用,一种用于管理后台)。在这种情况下,你可以为页面组件添加一个 getLayout 属性。
修改
_app.js首先,修改
_app.js以支持getLayout函数。jsx// pages/_app.js import '../styles/globals.css'; export default function MyApp({ Component, pageProps }) { // 如果页面有 getLayout 方法,则使用它 const getLayout = Component.getLayout || ((page) => page); return getLayout(<Component {...pageProps} />); }在页面中指定布局
现在,你可以在需要特定布局的页面中定义
getLayout。jsx// pages/dashboard.js import AdminLayout from '../components/AdminLayout'; export default function DashboardPage() { return ( <div> <h1>Admin Dashboard</h1> {/* ... */} </div> ); } // 定义该页面的布局 DashboardPage.getLayout = function getLayout(page) { return <AdminLayout>{page}</AdminLayout>; };对于不需要特殊布局的页面,它们将默认不使用任何布局,或者你可以提供一个默认布局。
3. App Router 中的布局 (Next.js 13+)
在 Next.js 13 引入的 App Router 中,布局的管理变得更加原生和强大。
layout.js文件:你可以在任何路由段中创建一个layout.js文件来定义共享 UI。这个布局会应用于该路由段及其所有子路由。
示例:app/dashboard/layout.js
// app/dashboard/layout.js
export default function DashboardLayout({ children }) {
return (
<section>
{/* 共享的仪表盘导航 */}
<nav>Dashboard Nav</nav>
{children}
</section>
);
}这个布局会自动包裹 app/dashboard/page.js 以及 app/dashboard/settings/page.js 等所有子页面。
总结
- 组件是构建 UI 的基本单位,应保持独立和可重用。
- 共享布局可以通过创建一个
Layout组件并在_app.js中使用它来实现。 - 对于需要多种布局的复杂应用,每页布局模式提供了更大的灵活性。
- 在 App Router 中,布局通过
layout.js文件以更结构化的方式进行管理。
在最后一章中,我们将为你提供一些有用的学习资源,帮助你继续深入学习 Next.js。