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

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.mrgr.cn/news/100660.html

相关文章:

  • 【MCP Node.js SDK 全栈进阶指南】高级篇(5):MCP之微服务架构
  • runpod team 怎么设置自己的ssh key呢?
  • 【统计方法】交叉验证:Resampling, nested 交叉验证等策略 【含R语言】
  • 如何用python脚本把一个表格有4万多条数据分为两个文件表,每个2万条数据?
  • unity Orbbec Femto Bolt接入unity流程记录 AzureKinectExamples 插件 使用记录
  • Android WIFI体系
  • LeetCode热题100--53.最大子数组和--中等
  • 2025.4.29总结
  • Nacos源码—2.Nacos服务注册发现分析四
  • Ansible 铸就 Linux 安全之盾(Ansible Builds Linux Security Shield)
  • Python初学 有差异的知识点总结(一)
  • ARPG游戏和MMORPG经济形态区别以及对经济循环的思考
  • GoogleTest:在Ubuntu22.04安装
  • 热度大幅度下降,25西电经济与管理学院(考研录取情况)
  • Python数据结构与算法(5)——动态规划
  • 聊透多线程编程-线程互斥与同步-13. C# Mutex类实现线程互斥
  • 目标检测篇---faster R-CNN
  • HarmonyOS NEXT 诗词元服务项目开发上架全流程实战(一、项目介绍及实现效果)
  • CogCoM: A Visual Language Model with Chain-of-Manipulations Reasoning 学习笔记
  • 【金仓数据库征文】加速数字化转型:金仓数据库在金融与能源领域强势崛起