当前位置: 首页 > ai >正文

Next框架学习篇 ✅

写在最前:好难啊我走召🤯🤯🤯

目录&待解决的问题

next版本:13.5.1
node版本:22.15.0
🔗 Next中文文档

目录

1️⃣ 页面
2️⃣ 应用级路由
3️⃣ CSS相关

待解决的问题

1️⃣ 如何做嵌套路由
2️⃣ 如何做动态路由表
3️⃣ 如何集成mobx
4️⃣ 如何做客户端渲染


页面

假设在 /next_project/pages/home.tsx下我们export default了这样一个组件:

const HomePage = () => {return <div>HomePage</div>;
};
export default HomePage;

此时我们便可以在本地的http://localhost:3000/home中查看此组件,这便是使用Next脚手架搭建的应用中最基础的页面与组件的映射关系。这种约定方式很像微信小程序开发,也很像Egg。

此外,Next具有静态生成服务端渲染这两种预渲染模式。静态生成是Next推荐的最佳实践,即指HTML在应用构建时生成,并在每次页面请求时通过浏览器缓存被复用(CDN可以在没有额外配置的情况下缓存静态生成的页面以提高性能);服务端渲染指的是在每次请求时重新生成HTML。

静态生成

默认情况下,Next.js 使用静态生成来预渲染页面,正如上述Demo所编写的那样。此外,Next官方的文档中还提供了需要外部数据的静态生成的页面的做法,此处只将其与客户端渲染进行对比,因为煮啵始终觉得既然走到了“需要外部数据”这个份上了,那页面就具有实时性的需求,应该用服务端渲染或者客户端渲染才合理。 见下面Demo:

import { useEffect, useState } from "react";
interface PageProps { posts: Array<{ title: string }> }const UserPage = (props: PageProps) => {const { posts: postsA } = props; // postsA在Next静态生成时注入const [postsB, setPostsB] = useState<Array<{ title: string }>>([]);useEffect(() => {setPostsB([{ title: "Post 3" }, { title: "Post 4" }]);}, []);return (<div className="user-page"><h1>User Page</h1>{postsA.map((post) => <div>{post.title}</div>)}{postsB.map((post) => <div>{post.title}</div>)}</div>);
};// 此函数会在构建的时候执行一次
export async function getStaticProps() {const result = await new Promise((res) => {const posts = [{ title: "Post 1" }, { title: "Post 2" }];res(posts);});return { props: { posts: result } };
}export default UserPage;

Q1:“静态生成”生成的到底是啥玩意?
A1:生成的是“可预见的DOM”。 说了跟白说一样哈哈。 对比我们熟悉的用Vite构建的单页面应用或许更好理解,这种时候我们请求的HTML文件中通常只是一个id为root的div,这种HTML通常只是一个“空壳”。但是在Next的静态构建中我们请求的HTML文件中却出现了用postsA来填充的多个div,这部分DOM是不依赖于“水合”这个过程,就可以事先渲染出来的;但是用postsB来填充的多个div并没有出现在HTML文件中,其行为更像我们熟悉的“客户端渲染”。

区别Next静态生成Vite构建的SPA应用
HTML中是否含有页面实际内容✅ 有完整的UI内容通常只是一个id为root的div
首屏是否无需JS即可看到UI✅ 可以,即使可能不完整❌ 看不到
是否能用SEO抓取✅ 很适合❌ 几乎抓不到
是否支持预渲染多页面✅ 多页面静态生成❌ 本质只有一个HTML + JS

服务端渲染

在Next中我们可以通过实现getServerSideProps函数来实现服务端渲染,详见下面的Demo:

const HomePage = ({ data }: any) => {return (<div><div>name: {data.name}</div><div>age: {data.age}</div></div>);
}export async function getServerSideProps() {// 每次请求页面时,都会执行此函数console.log("getServerSideProps");const result = await new Promise((res) => {const data = { name: "Pro", age: 25 };res(data);});console.log("result", result);return { props: { data: result } };
}export default HomePage;

后续我们每次请求http://localhost:3000/home的时候,两次console.log()都是在服务端执行的(开发模式下即为VSCode),且每次对http://localhost:3000/home的请求返回的响应状态码都是200(说明是在请求时实时返回的,走不了缓存;如果用的是静态生成,从第二次请求开始返回的便是304

需要重申的是,不管是静态生成的HTML还是服务端渲染后返回的HTML都可以依赖外部数据来填充HTML页面,具体做法可参考Next文档中此章的内容。


应用级路由

路由嵌套 & 重定向

需求:想在Next中构建一个带左侧导航栏和右侧内容区的“后台管理布局”,并通过导航切换子页面,如admin/dictadmin/notice,并将后台首页重定向到admin/notice

直接开撸:

// pages/admin/index.tsx
import Link from "next/link";
import { ReactNode, useEffect } from "react";
import { useRouter } from "next/router";
export default function AdminLayout({ children }: { children: ReactNode }) {const router = useRouter();useEffect(() => {// 页面加载后立即跳转到公告管理router.pathname === "/admin" && router.replace("/admins/notice");}, []);return (<div style={{ display: "flex", height: "100vh" }}>{/* 左侧导航栏 */}<div style={{ width: 200, background: "#f2f2f2", padding: 20 }}><nav style={{ display: "flex", flexDirection: "column", gap: 10 }}><Link href="/admins/dict">词典管理</Link><Link href="/admins/notice">公告管理</Link></nav></div>{/* 右侧内容 */}<div style={{ flex: 1, padding: 20 }}>{children}</div></div>);
}// pages/admin/notice.tsx
import AdminLayout from ".";
const NoticePage = () => {return <AdminLayout>Notice Page</AdminLayout>;
};
export default NoticePage;// pages/admin/dict.tsx
import AdminLayout from ".";
const DictPage = () => {return <AdminLayout>Dict Manege</AdminLayout>;
};
export default DictPage;

路由守卫

虽然Next的路由是文件系统驱动的,且没有像react-router那样的显式路由表,但Next仍提供了多种路由守卫方式。但这部分内容的讨论脱离了煮啵想学的“服务端渲染”的内容,更偏向于实际开发的应用,后续开发到这中需求再详细补充,此处仅对几种组件内的守卫方法做简单介绍。其实就是懒。

控制方式触发时机用法举例适用场景
页面组件内守卫客户端useEffect + 跳转判断登陆态,客户端重定向
getServerSideProps服务端判断cookie/token,重定向或403页面级SSR权限控制
Next中间件middleware.ts请求到达前在Edge上做重定向拦截全局路径守卫,高性能

懒加载

Next已经实现了基于路由的自动懒加载,以上述Demo为例,只要还未进入到admin/dict页面,那么pages/admin/dict.tsx的代码便不会被加载。此处或许还有更高级的用法,后续见到了再补充吧。


CSS相关

有空再写


http://www.xdnf.cn/news/2895.html

相关文章:

  • Nginx部署与源码编译构建LAMP
  • Java基础 4.29
  • OpenJDK 1.8中-Xloggc参数下GC日志覆盖与追加模式深度解析
  • 软文发稿:媒体发稿的关键策略及实战价值
  • Android Studio中OpenCV应用详解:图像处理、颜色对比与OCR识别
  • 水污染检测数据集VOC+YOLO格式2487张4类别
  • mangodb的数据库与集合命令,文档命令
  • 字节跳动社招面经 —— BSP驱动工程师(4)
  • 【计算机网络】DHCP——动态配置ip地址
  • 仿真干货|云端CAE实战——OpenRadioss物品碰撞模拟分析
  • day006
  • FPGA 39 ,FPGA 网络通信协议栈进阶,RGMII、ARP 与 UDP 协议与模块设计( RGMII、ARP、UDP原理与模块设计 )
  • 基于STM32的中点圆算法,画空心圆的函数
  • 【MongoDB篇】MongoDB的数据库操作!
  • 通义千问最新一代大语言模型Qwen3发布了
  • 前端漏洞不扫描理由
  • 各服务日志: Grok正则解析
  • 高瓴资本张磊的顶级价值投资之道
  • 通信原理第七版与第六版区别附pdf
  • Alibaba国际站商品详情AP接口概述,json数据示例返回参考
  • 分布式系统的基石:从 CAP 理论到一致性算法全解析(简化版)
  • Centos 7系统 宝塔部署Tomcat项目(保姆级教程)
  • Spring知识点梳理
  • 【算法练习】归并排序和归并分治
  • 【C++贪心】P6023 走路|普及
  • 2025.4.29总结
  • 训练神经网络的批量标准化(使用 PyTorch)
  • Ubuntu 系统上部署 Kubernetes 的完整指南
  • KUKA机器人关机时冷启动介绍
  • 得物 小程序 6宫格 分析