Tube - Basic Layout

  • Image組件
    <Image
      src="/logo.svg"
      width={50}
      height={50}
      alt="Logo"
    />
    
    • Image 組件來自 Next.js,默認(rèn)開啟懶加載
    • widthheight 默認(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容