在 Next.js 應用中,你可以通過多種方式實現某些頁面全屏、某些頁面帶菜單/頁眉/頁腳的需求。以下是幾種實現方案:
方案一:使用多個布局組件
1. 創建不同的布局組件
// app/default-layout.tsx
import Header from '@/components/header';
import Sidebar from '@/components/sidebar';
import Footer from '@/components/footer';export default function DefaultLayout({ children }: { children: React.ReactNode }) {return (<><Header /><div className="flex"><Sidebar /><main className="flex-1 p-4">{children}</main></div><Footer /></>);
}
// app/fullscreen-layout.tsx
export default function FullscreenLayout({ children }: { children: React.ReactNode }) {return (<div className="w-full h-full">{children}</div>);
}
2. 在頁面中指定布局
// app/dashboard/page.tsx
import DefaultLayout from '../default-layout';export default function DashboardPage() {return (<DefaultLayout>{/* 頁面內容 */}</DefaultLayout>);
}
// app/login/page.tsx
import FullscreenLayout from '../fullscreen-layout';export default function LoginPage() {return (<FullscreenLayout>{/* 全屏頁面內容 */}</FullscreenLayout>);
}
方案二:使用布局選擇器
1. 創建布局選擇器組件
// app/layout-selector.tsx
'use client';import { usePathname } from 'next/navigation';
import DefaultLayout from './default-layout';
import FullscreenLayout from './fullscreen-layout';const fullscreenPaths = ['/login', '/register', '/fullscreen-page'];export default function LayoutSelector({ children }: { children: React.ReactNode }) {const pathname = usePathname();const isFullscreen = fullscreenPaths.some(path => pathname.startsWith(path));if (isFullscreen) {return <FullscreenLayout>{children}</FullscreenLayout>;}return <DefaultLayout>{children}</DefaultLayout>;
}
2. 修改根布局
// app/layout.tsx
import LayoutSelector from './layout-selector';export default function RootLayout({ children }: { children: React.ReactNode }) {return (<html><body><LayoutSelector>{children}</LayoutSelector></body></html>);
}
方案三:使用平行路由(Next.js 13.4+)
1. 創建平行路由結構
app/(fullscreen)/login/page.tsxregister/page.tsx(default)/dashboard/page.tsxsettings/page.tsxlayout.tsx
2. 修改根布局
// app/layout.tsx
export default function RootLayout({children,fullscreen,default: defaultLayout
}: {children: React.ReactNode;fullscreen: React.ReactNode;default: React.ReactNode;
}) {return (<html><body>{fullscreen || (<><Header /><div className="flex"><Sidebar /><main className="flex-1 p-4">{defaultLayout}</main></div><Footer /></>)}{children}</body></html>);
}
方案四:使用頁面元數據標記
1. 在頁面中添加元數據
// app/dashboard/page.tsx
export const metadata = {layout: 'default'
};export default function DashboardPage() {// ...
}
// app/login/page.tsx
export const metadata = {layout: 'fullscreen'
};export default function LoginPage() {// ...
}
2. 修改布局組件
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {// 獲取當前路由的元數據(需要自定義實現)const pathname = usePathname();const metadata = getPageMetadata(pathname); // 自定義函數if (metadata?.layout === 'fullscreen') {return (<html><body>{children}</body></html>);}return (<html><body><Header /><div className="flex"><Sidebar /><main className="flex-1 p-4">{children}</main></div><Footer /></body></html>);
}
最佳實踐建議
- 簡單應用:使用方案一(多個布局組件)最為直接
- 中等復雜度:方案二(布局選擇器)更易于維護
- 大型應用:方案三(平行路由)提供最好的靈活性
- 需要SEO控制:方案四(元數據標記)可以與SEO配置結合
樣式處理技巧
對于全屏頁面,可以添加全局樣式:
/* globals.css */
.fullscreen-page {height: 100vh;width: 100vw;overflow: hidden;
}
然后在全屏布局組件中應用:
<div className="fullscreen-page">{children}
</div>
這樣就能確保全屏頁面真正占滿整個視口。