next.js-学习2
next.js-学习2
- 1. https://nextjs.org/learn/dashboard-app/getting-started
- 2. 模拟的数据
- 3. 添加样式
- 4. 字体,图片
- 5. 创建布局和页面
- 页面导航

1. https://nextjs.org/learn/dashboard-app/getting-started
/app
: Contains all the routes, components, and logic for your application, this is where you’ll be mostly working from./app/lib
: Contains functions used in your application, such as reusable utility functions and data fetching functions./app/ui
: Contains all the UI components for your application, such as cards, tables, and forms. To save time, we’ve pre-styled these components for you./public
: Contains all the static assets for your application, such as images.- Config Files: You’ll also notice config files such as
next.config.ts
at the root of your application. Most of these files are created and pre-configured when you start a new project usingcreate-next-app
. You will not need to modify them in this course.
2. 模拟的数据
app/lib/placeholder-data.ts 这些是模拟的数据
3. 添加样式
-
/app/layout.tsx中加入**import ‘@/app/ui/global.css’;**支持全局样式,global.css中@tailwind是css框架
-
在代码中加@tailwind样式
<h1 className="text-blue-500">I'm blue!</h1> <div className="relative w-0 h-0 border-l-[15px] border-r-[15px] border-b-[26px] border-l-transparent border-r-transparent border-b-black" />
如果是不想直接加可以封装个css类引用,创建文件/app/ui/home.module.css,写入
.shape { height: 0; width: 0; border-bottom: 30px solid black; border-left: 20px solid transparent; border-right: 20px solid transparent; }
在/app/page.tsx中导入import styles from ‘@/app/ui/home.module.css’;
使用
,这样可以有效的隔离样式的侵入性动态设置样式,/app/ui/invoices/status.tsx中的clx,可以根据传入的status动态显示样式,代码如下:
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',
},
)}
>
// ...
)}
4. 字体,图片
/app/ui/fonts.ts 如果自己加字体浏览器会二次渲染,布局变化可能会影响性能,如果是用next/font在初始化加载的时候字体会嵌入进去,不会二次渲染,性能提升。
添加谷歌字体,创建文件/app/ui/fonts.ts
import { Inter } from 'next/font/google';
export const inter = Inter({ subsets: ['latin'] });
//增加第二种字体
import { Lusitana } from 'next/font/google';
export const lusitana = Lusitana({
subsets: ['latin'],
weight: ['400', '700'], // Normal and bold weights
});
在/app/layout.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/page.tsx中使用
import { lusitana } from '@/app/ui/fonts'; //引入字体
//修改p标签的字体,这次页面字体整体变小了
<p className={lusitana.className}>
加载图片,不同大小屏幕显示正常,优化加载,在/app/page.tsx中使用
原文参考:https://nextjs.org/learn/dashboard-app/optimizing-fonts-images#why-optimize-images
hidden md:block//在小屏幕(md
以下,比如手机)上,元素会 隐藏,因为 hidden
优先级较高。
当屏幕宽度达到 md
尺寸(通常是平板和桌面设备)及以上时,元素会 显示,且显示为块级元素(block
)。
import Image from 'next/image';//引入图片
<Image
src="/hero-desktop.png"
width={1000}
height={760}
className="hidden md:block"//桌面可见
alt="Screenshots of the dashboard project showing desktop version"
/>
<Image
src="/hero-mobile.png"
width={1000}
height={760}
className="block md:hidden"//平板或者手机可见
alt="Screenshots of the dashboard project showing desktop version"
/>
5. 创建布局和页面
layout.tsx
:为多个页面提供共享布局。
page.tsx
:为每个路由提供独特的页面内容
例如这种嵌套布局。举例: 如果你有一个管理页面,你可以在管理页面的 layout.tsx
中定义一个不同的布局(这里的布局也会用根布局的布局属性),而其他页面仍然使用根布局。
/app
/layout.tsx // 根布局
/admin
/layout.tsx // 管理页面布局
/dashboard/page.tsx
/settings/page.tsx
/home
/page.tsx
创建:/app/dashboard/page.tsx,访问:http://localhost:3000/dashboard
export default function Page() {
return <p>Dashboard Page</p>;
}
创建面板
/app/dashboard/customers/page.tsx
export default function Page() {
return <p>Customers Page</p>;
}
/app/dashboard/invoices/page.tsx
export default function Page() {
return <p>Invoices Page</p>;
}
/app/dashboard/layout.tsx 导入SideNav 组件到布局
import SideNav from '@/app/ui/dashboard/sidenav';
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen flex-col md:flex-row md:overflow-hidden">
<div className="w-full flex-none md:w-64">
<SideNav />
</div>
<div className="flex-grow p-6 md:overflow-y-auto md:p-12">{children}</div>
</div>
);
}
如图:
页面导航
/app/ui/dashboard/nav-links.tsx使用link标签替换a标签,这样点击导航就不会全局刷新了,避免了全局加载。
import Link from 'next/link';//添加link
a标签改为 </Link>标签
/app/ui/dashboard/nav-links.tsx使用usePathname和clsx让点击导航栏,动态显示点击的那个导航栏变蓝
'use client';//改为客户端组件,因为usePathname需要浏览器支持
import { usePathname } from 'next/navigation'; //使用usePathname
import clsx from 'clsx';
const pathname = usePathname(); //NavLinks()使用
//link中的className改为
className={clsx(
'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
{
'bg-sky-100 text-blue-600': pathname === link.href,
},
)}