-
Image組件
<Image
src="/logo.svg"
width={50}
height={50}
alt="Logo"
/>
- Image 組件來自 Next.js,默認(rèn)開啟懶加載
-
width 和 height 默認(rèn)是 required
-
src 可以是 internal path 或者 external url,使用 external url 時需要在 next.config.js 文件中配置 remotePatterns
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
remotePatterns: [
// uploadthing 的圖片
{
protocol: 'https',
hostname: 'szxu79mai4.ufs.sh'
}
]
}
};
export default nextConfig;
-
修改字體 src/app/layout.tsx
- 刪除原有字體,導(dǎo)入新字體
import { Inter } from "next/font/google";,并修改 <body>的className
...
import { Inter } from "next/font/google";
...
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "New Tube",
description: "New Tube",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={ inter.className }
>
{children}
</body>
</html>
);
}
-
App Router folders
- Next.js 15 使用
app/ 目錄結(jié)構(gòu)創(chuàng)建路由,路由基于文件夾結(jié)構(gòu)自動生成
src/
app/
page.tsx // 根路徑 "/"
layout.tsx // 根布局,作用于所有頁面
home/
page.tsx // "/home"
videos/
[videoId]/
page.tsx // 動態(tài)路由 "/videos/:[videoId]"
- 關(guān)于在動態(tài)路由中獲取url參數(shù),Next.js 15已將其修改為異步,無需手動傳遞,會從當(dāng)前url中自動解析,具體文檔可參考 Dynamic APIs are Asynchronous,在我們當(dāng)前使用的服務(wù)器組件中可以用如下辦法獲取參數(shù):
// 將params聲明為一個Promise類型
interface VideoIdPageProps{
params: Promise<{ videoId: string }>;
}
const Page = async ({ params }: VideoIdPageProps) => {
// 通過await獲取異步參數(shù)
const { videoId } = await params;
return (
<div>
video ID: { videoId }
</div>
)
}
export default Page;
-
Layout.tsx
- 在 App Router 中用于構(gòu)建頁面布局的組件,通常也用于創(chuàng)建可重用的布局(導(dǎo)航、側(cè)邊欄等),所以所有子頁面會嵌套在 layout.tsx 的結(jié)構(gòu)中
- 子文件夾可以有自己的 layout.tsx
- 如下目錄結(jié)構(gòu)中,會先渲染 app/layout.tsx,再渲染 app/videos/layout.tsx
- 必須包含
children 作為插槽,children 是頁面內(nèi)容
// 目錄結(jié)構(gòu)
src/
app/
page.tsx
layout.tsx // 根布局
videos/
page.tsx
layout.tsx // 子路由自己的layout
[videoId]/
page.tsx // 動態(tài)路由 "/videos/:[videoId]"
// app/videos/layout.tsx
interface LayoutProps {
children: React.ReactNode;
}
const Layout = ({ children }: LayoutProps) => {
return (
<div>
<div className="p-4 bg-red-300 w-full">
this is a navbar
</div>
{ children }
</div>
)
}
export default Layout;
-
Route Groups
// 當(dāng)前目錄結(jié)構(gòu)
src/
app/
layout.tsx // 根布局
(home)/
layout.tsx
page.tsx
modules/
home/
ui/
layouts/
home-layout.tsx
-
關(guān)于項(xiàng)目結(jié)構(gòu)
- 基于上面的目錄,app 文件夾中只放置 route 相關(guān)的文件
- 其他components、hooks、apis、server、utils等等都將放在 modules 文件夾下
-
Sidebar組件
-
SidebarProvider 是根級組件,用于提供側(cè)邊欄的上下文
- 將其他組件寫在
SidebarProvider 內(nèi)部,保證這些組件都能訪問到其提供的有關(guān)狀態(tài)
-
<SidebarMenuButton>默認(rèn)渲染一個button,但使用了asChild就可以渲染成<SidebarMenuButton>包裹的組件了
<SidebarMenuButton
tooltip={item.title}
asChild
isActive={false}
onClick={e => { }}
>
<Link href={item.url} className="flex items-center gap-4">
<item.icon />
<span className="text-sm">{item.title}</span>
</Link>
</SidebarMenuButton>
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。