001 基本知识
目录
基础概念:
- Next.js 14 的 App Route
layout.ts
与page.ts
所用技术组件(Tech Stack)
- (待补)
本文对应 Next.js Learn 入门教程的第 1-3 章。
搭起脚手架
https://nextjs.org/learn/dashboard-app/getting-started
创建项目
bash
npx create-next-app@latest nextdash --use-npm \
--example \
"https://github.com/vercel/next-learn/tree/main/dashboard/starter-example"
在 nextdash
目录下创建了项目,为复制的项目模板。
目录结构
├── app ├── node_modules ├── package.json ├── public ├── scripts ├── tailwind.config.ts └── tsconfig.json
其中项目主目录是:/app
app ├── layout.tsx ├── lib │ ├── data.ts │ ├── definitions.ts │ ├── placeholder-data.js │ └── utils.ts ├── page.tsx └── ui ├── acme-logo.tsx ├── button.tsx ├── customers ├── dashboard ├── global.css ├── invoices ├── login-form.tsx ├── search.tsx └── skeletons.tsx
添加 CSS 样式
tailwind
& global.css
在 /app/layout.tsx
添加:
tsx
import '@/app/ui/global.css';
/app/ui/global.css
css
@tailwind base;
@tailwind components;
@tailwind utilities;
CSS Modules
css module: https://nextjs.org/learn/dashboard-app/css-styling#css-modules
docs: https://nextjs.org/docs/basic-features/built-in-css-support
clsx
tsx
import clsx from 'clsx';
export default function InvoiceStatus({ status }: { status: string }) {
return (
<span
className={clsx(
'inline-flex items-center rounded-full px-2 py-1 text-sm',
{
'bg-gray-100 text-gray-500': status === 'pending',
'bg-green-500 text-white': status === 'paid',
},
)}
>
// ...
)}
字体与图片优化
字体
/app/ui/fonts.ts
tsx
import { Inter } from 'next/font/google';
export const inter = Inter({ subsets: ['latin'] });
/app/layout.tsx
tsx
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>{children}</body>
</html>
);
}
第二字体
/app/ui/fonts.ts
tsx
import { Inter, Lusitana } from 'next/font/google';
export const inter = Inter({ subsets: ['latin'] });
export const lusitana = Lusitana({
weight: ['400', '700'],
subsets: ['latin'],
});
/app/page.tsx
tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { lusitana } from '@/app/ui/fonts';
export default function Page() {
return (
// ...
<p
className={`${lusitana.className} text-xl text-gray-800 md:text-3xl md:leading-normal`}
>
<strong>Welcome to Acme.</strong> This is the example for the{' '}
<a href="https://nextjs.org/learn/" className="text-blue-500">
Next.js Learn Course
</a>
, brought to you by Vercel.
</p>
// ...
);
}
<AcmeLogo />
也使用这一字体,之前被注释掉,现在让其正常显示。
图片优化 <Image>
https://nextjs.org/docs/api-reference/next/image
在/app/page.tsx
增加图片:
tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';
export default function Page() {
return (
// ...
<div className="flex items-center justify-center p-6 md:w-3/5 md:px-28 md:py-12">
{/* Add Hero Images Here */}
<Image
src="/hero-desktop.png"
width={1000}
height={760}
className="hidden md:block"
alt="Screenshots of the dashboard project showing desktop version"
/>
</div>
//...
);
}
mobile hero image
tsx
<Image
src="/hero-mobile.png"
width={560}
height={620}
className="block md:hidden"
alt="Screenshot of the dashboard project showing mobile version"
/>
注意 css 的区别:
桌面版:
tsx
className="hidden md:block"
移动版
tsx
className="block md:hidden"
tsx 注释
tsx
return (
<>
{/* NOTE: comment in this code */}
</>
)