nextjs学习-基础知识
本文介绍些 NextJs 的一些基础知识:特性、功能、安装、结构目录、app router 以及 TailWind css,为了后续全栈开发博客和内管平台打下基础。
供自己以后查漏补缺,也欢迎同道朋友交流学习。
引言
我最近学习了 NextJs 相关知识,想通过边学边写博客边写简单 Demo 的形式来记录下,下面是有关我对 NextJs 的一些理解。会分为基础知识、前端开发、后端开发联调 3 个方面来介绍 NextJs 开发应用。
本文主要介绍一些 NextJs 的一些基础知识:特性、功能、安装、结构目录、app router 以及 TailWind css。
next.js介绍
Next.js 是一个用于构建全栈 Web 应用的 React 框架。你可以使用 React Components 来构建用户界面,并使用 Next.js 来实现附加功能和优化。
在底层,Next.js 还抽象并自动配置 React 所需的工具,例如打包、编译等。这使你可以专注于构建应用,而不是花时间进行配置。
为什么要学 Next.js
首先作为前端,需要对新的框架技术保持一定的敏感度。其次,经过一定的了解发现,Next.js 框架在 React 的基础上,提供了更多的特性,如:
- 性能优化:自动对 React 应用进行优化,包括
服务器端渲染、静态网站生成和代码分割,这些都有助于提升应用的加载速度和性能。 - SEO 友好:支持
服务器端渲染,它使得搜索引擎更容易索引你的页面,从而改善了SEO。 - API 路由:引入了新的
API路由功能,使得构建 API 和服务器端逻辑更加简单和直观。 - 静态和动态结合:允许你将
静态网站生成和服务器端渲染的优势结合起来,为你的用户提供最佳的体验。 - 就业机会:许多公司和组织使用 Next.js 构建他们的产品,学习
Next.js可以增加你的就业机会。
总的来说,Next.js 是一个强大的工具,可以帮助你构建快速、可扩展和易于维护的 Web 应用。学习 Next.js 不仅可以提升你的技术能力,也可以让你在前端开发领域保持竞争力。
主要功能
Next.js 的一些主要功能包括:
| 特性 | 描述 |
|---|---|
| 路由 | 基于文件系统的路由构建在服务器组件之上,支持布局、嵌套路由、加载状态、错误处理等。 |
| 渲染 | 使用客户端和服务器组件进行客户端和服务器端渲染。使用 Next.js 在服务器上进一步优化静态和动态渲染。在 Edge 和 Node.js 运行时上进行流式传输。 |
| 数据获取 | 通过服务器组件中的 async/await 简化数据获取,以及用于请求记忆、数据缓存和重新验证的扩展 fetch API。 |
| 样式 | 支持你喜欢的样式方法,包括 CSS 模块、Tailwind CSS 和 CSS-in-JS |
| 优化 | 图片、字体和脚本优化,以改善应用的核心网络生命和用户体验。 |
| TypeScript | 改进了对 TypeScript 的支持,提供更好的类型检查和更高效的编译,以及自定义 TypeScript 插件和类型检查器。 |
安装
Node.js 18.17或更高版本
# 创建项目
npx create-next-app@latest
目录结构
默认生成 TypeScript 、ESLint 和 Tailwind CSS 的 Next.js 项目。
.
├── README.md
├── app // 应用路由
│ ├── favicon.ico
│ ├── globals.css // 全局css
│ ├── layout.tsx // 全局布局
│ └── page.tsx // 全局页面
├── next-env.d.ts // Next.js 的 TypeScript 声明文件
├── next.config.mjs
├── package.json
├── postcss.config.mjs
├── public
│ ├── next.svg
│ └── vercel.svg
├── tailwind.config.ts
└── tsconfig.json
路由基础知识
NextJs 拥有两套路由(两者兼容):
页面路由 Pages Router:在pages目录下创建对应的文件或者目录即是一个路由。应用路由 App Router:从版本13.4起的默认路由模式,任意目录可访问的页面,必须定义为page.tsx。
应用路由
默认我们学习应用路由模式。
- 在
app目录下新建登录注册、列表、详情页面
.
├── detail
│ └── page.tsx
├── list
│ └── page.tsx
├── login
│ └── page.tsx
为了项目的结构更清晰,可以在app目录下,新建一个(pages)文件夹用于存放页面路由。
(pages)
├── detail
│ └── page.tsx
├── list
│ └── page.tsx
├── login
│ └── page.tsx
路由跳转
第一种使用导航:
import Link from 'next/link'
export default function Page() (
<Link href="/dashboard">Dashboard</Link>
)
第二种使用useRouter:
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
路由参数
获取路由参数
import { useSearchParams, usePathname } from 'next/navigation'
动态路由
| 路由 | params 类型定义 |
|---|---|
| app/blog/[slug]/page.js | { slug: string } |
| app/shop/[...slug]/page.js | { slug: string[] } |
| app/shop/[[...slug]]/page.js | { slug?: string[] } |
| app/[categoryId]/[itemId]/page.js | { categoryId: string, itemId: string } |
Tailwind CSS
Tailwind CSS 是一个功能类优先的 CSS 框架,它允许你通过简单的类来快速创建视图样式。因为 nextJS 默认集成了 Tailwind CSS,所以我们还是很有必要了解它的。
基本使用
Tailwind 写起来和以前的 Bootstrap很相似,原子化的类名,通过组合类名来快速创建样式。下面介绍下最基本的样式写法:
盒模型-宽高边距
<!-- 预定义数值类(w-数值、h-数值) -->
<!-- w-1 的 1 表示 0.25 rem,即 4 px,以此类推,w-20 表示 5 rem,即 width: 80px; -->
<div class="w-20 h-20">width and height</div>
<!-- 手动书写任意值(w-[]、h-[]) -->
<div class="w-[80px] h-[80px]">width and height</div>
<!-- 百分比(w-分子/分母、h-分子/分母) -->
<div class="w-1/2 h-1/3">width and height</div>
<!--
外边距
mt-* -> margin-top: _;
mb-* -> margin-bottom: _;
ml-* -> margin-left: _;
mr-* -> margin-right: _;
mx-* -> margin-left: _; margin-right: _;
my-* -> margin-top: _; margin-bottom: _;
-->
<div class="mr-2">margin</div>
<!--
内边距
pt-* -> padding-top: _;
pb-* -> padding-bottom: _;
pl-* -> padding-left: _;
pr-* -> padding-right: _;
px-* -> padding-left: _; padding-right: _;
py-* -> padding-top: _; padding-bottom: _;
-->
<div class="px-10 py-5">padding</div>
<!--
子元素之间的间距
space-x-* -> 水平方向排列间隔为 _;
space-y-* -> 垂直方向排列间隔为 _;
本例:
space-x-2 -> 水平方向排列间隔为 8px;
-->
<div class="space-x-2">
<div class="inline-block">01</div>
<div class="inline-block">02</div>
<div class="inline-block">03</div>
</div>
<!--
边框
border-* -> border: _;
如果想要设定某一方向的边框:border-*-数值,参考前面的外边距样式
边框颜色 -> border-颜色-数值
线类型 -> border-solid border-dashed border-dotted border-double
-->
<div class="border-2 border-red-500">border</div>
文本
<!--
字体大小
text-数值、text-[]
text-base、text-md、text-[16px] 都是一样的,取浏览器的字体默认值 16px。
-->
<p class="text-sm">text text text</p>
<p class="text-base">text text text</p>
<p class="text-md">text text text</p>
<p class="text-[16px]">text text text</p>
<p class="text-lg">text text text</p>
<p class="text-xl">text text text</p>
<!--
字体斜体与加粗
italic
font-thin、font-light、font-normal、font-bold、font-black
-->
<p class="italic font-thin">text text text</p>
<!--
文本对齐
text-left、text-center、text-right、text-justify
-->
<p class="text-left">text text text</p>
<!--
颜色
字体颜色:text-颜色-数值 text-red-500
边框颜色:border-颜色-数值 border-2 border-red-500
背景颜色:bg-颜色-数值/透明度 bg-red-500
背景渐变色图像:bg-gradient-to-方向 from-颜色-数值 to-颜色-数值
-> bg-gradient-to-r from-purple-500 to-pink-500
-->
<p class="text-red-500">文本颜色</p>
<p class="border-2 border-red-500">边框颜色</p>
<p class="bg-red-500">背景颜色</p>
<p class="bg-orange-500/75">背景颜色(75% 透明度)</p>
<div class="bg-gradient-to-r from-purple-500 to-pink-500">向右渐变(purple-500 -> pink-500)</div>
布局
<!--
弹性布局 flex
flex -> display: flex;
flex-1 -> flex: 1 1 0%;
水平垂直居中
justify-center -> justify-content: center;
items-center -> align-items: center;
垂直排列
flex-col -> flex-direction: column;
-->
<div class="flex h-screen">
<div class="bg-red-500 w-48">left</div>
<div class="bg-blue-500 flex-1">right</div>
</div>
<!--
网格布局 grid
grid -> display: grid;
grid-cols-2 -> grid-template-columns: repeat(2, minmax(0, 1fr));
水平垂直居中
place-items-center -> place-items: center;
-->
<div class="grid grid-cols-2 h-screen">
<div class="bg-red-500">left</div>
<div class="bg-blue-500">right</div>
</div>
定位
<!--
relative + absolute
relative -> position: relative;
absolute -> position: absolute;
top-10 -> top: 2.5rem; /* 40px */
left-10 -> left: 2.5rem; /* 40px */
其他方向
bottom-* -> bottom: _;
right-* -> right: _;
层级
z-index
其他定位方式
fixed
sticky
-->
<div class="relative bg-red-500">
<p>父容器</p>
<div class="absolute top-10 left-10 bg-blue-500">
子元素A
</div>
</div>
伪类和伪元素
<!--
伪类
hover: 鼠标触摸时的效果。
focus: 按钮、输入框等表单控件聚焦时出现的效果。
active: 鼠标按住时就打开了 active 激活状态。
-->
<div class="hover:bg-red-500">hover</div>
<input type="text" class="px-2 outline focus:outline-1 focus:outline-blue-500" placeholder="请聚焦这里..." />
<button class="active:bg-red-500">button</button>
过渡和动画
<!--
形变 transform
平移 translate-[x/y]-数值 -> translate-x-10 -> transform: translateX(2.5rem);
旋转 rotate-数值 -> rotate-45 -> transform: rotate(45deg);
缩放 scale-数值 scale-[x/y]-数值 -> scale-50 -> transform: scale(0.5);
倾斜 skew-[x/y]-数值
-->
<div class="translate-x-10 translate-y-10 size-20 bg-red-500">translate</div>
<div class="rotate-45 size-20 bg-red-500">rotate</div>
<div class="scale-50 size-20 bg-red-500">scale 0.5</div>
<!--
过渡 transition
持续时间 duration-数值
时间函数 ease-*
延迟 delay-数值
-->
<div class="transition xxx">transition</div>
<!--
动画 animate
animate-*
-->
<div class="animate-xxx">animate</div>
其他进阶样式需要看官网文档或系列博客去学习。
图像优化
使用具有自动图像优化功能的 <Image> 组件,通过断点 md 来自适应展示图片。
<Image
src="/xxx.png"
width={1000}
height={760}
className="hidden md:block"
/>