Nextjs 学习笔记
一、导航相关
1、客户端导航:Nextjs 的前端部分提供内置的「文件系统路由」+ Link
- Nextjs 13.x 版本开始,
<Link>
组件在使用时不用再写<a>
标签,因为在渲染时会把 Link 标签解析为 a 标签- 实现了「客户端导航」的方式,浏览器不会重新加载整个页面(a标签会触发重新刷新整个页面
- Nextjs 13.x 版本开始,「文件系统路由」从
pages/index.js
[旧方式]逐渐改为src/app/page.tsx
[新app模式]- 旧方式缺点:旧方式容易上手,按文件路径即可推论路由,但复杂嵌套需要写赘余代码
- 新方式优点:支持自定义共享布局,在
src/app/layout.tsx
可自定义共享的布局(导航栏等)
2、代码分割:Nextjs 会自动进行
3、页面预加载 prefetching
:只要有 Link 标签出现在视口,Nextjs 会自动预取 Link 关联的页面代码 -> 点击跳转时后台已经加载好页面了 -> 秒切
二、静态资源加载
包括 css、image、public 文件
1、内置 css 、 sass、css-in-js
2、支持 css Module:
-
解决的核心问题: nextjs 中 css 全局命名空间问题,将类名进行局部化处理,使得每个组件的样式只在组件内部生效 + 方便 code splitting 代码分割
-
使用方式:很简单,把
style.css
改写/标记为style.module.css
即可,其中的类名会被转换为独一无二的标识符
3、全局变量
- 旧方法:在
pages/_app.js
中 import 引入全局 css 文件,利用_app.js
是整个应用的顶层组件特性,_app.js
包裹了所有页面的组件,引入的样式自然就应用到了全局 - 新方法:
src/global.css
三、预渲染
默认情况下,Nextjs 会预渲染每个 page(也就是 预先为每个 page 生成 HTML 文件,而不是由 客户端 js 来生成 - 所以下面说的方法都是在「服务端」执行的,都不会被打包进 js bundle 里面
- 形式1:静态生成 - 生成 HTML 时机是「构建时」,并在每次页面请求时「重复使用」
- 在生产环境中,运行
next build
为该页面生成一次 HTML,之后被 CDN 缓存(托管 - 快) - 在开发环境/本地环境中,getStaticProps runs on every request
- 在生产环境中,运行
- 形式2:服务端渲染 - 生成时机是「每次页面请求时重新生成 HTML」
1、静态生成(static generation):别名SSG
这种静态生成的页面,分为「不带数据」(默认)的静态页面和「带数据」的静态页面。
需要获取外部数据的静态生成:
- 页面内容 取决于数据 – getStaticProps
- 该函数在「构建时」被调用,在预渲染时,将 props 作为参数传入页面
- [动态路由]paths 路径取决于数据 – getStaticPaths
- 例如使用
src/app/[id].tsx
来动态访问文件 - 该函数在「构建时」被调用,指定要被与渲染的数据
- 例如使用
nextjs 中 补丁 fetch 在客户端和服务端都可以执行,不需要再 import
// getStaticPaths、getStaticProps - 在同一文件,通过 export 导出 async 的异步函数
function Blog({posts}) {
// part① A React Component to render this page
return <ul>{posts.map((it) => (<li>{it.title}</li>))}</ul>
}
export async function getStaticPaths() {
// part② getStaticPaths which returnsn an array of possible values for ids
const res = await fetch('http://xxxx/posts'); // 外部查询
const post = await res.json();
const paths = posts.map(it => ({ params: { id: it.id } })); // 传递 params 数据,params 中的属性名和文档的 [id].tsx 的 key 相同
return { paths , fallback: false } // 其他非 paths 的路由为 404
}
export async funciton getStaticProps({ params }){ // 入参来源于 getStaticPaths
// part③ getStaticProps which fetches necessary data for the post with id
const res = await fetch(`http://xxxx/posts/${params.id}`);
const post = await res.json(); // 外部查询
return { props: { posts } } // 向页面传递博文数据
}
export default Blog
2、服务端渲染(server-side rendering):别名SSR/动态渲染
服务端在页面被请求时,执行当前页面内导出的异步函数 getServerSideProps 后再进行预渲染
- 写法类似于 getStaticProps,只是执行时机不同 - 构建时和请求时
四、客户端渲染
如果不需要预渲染,则可以采用客户端渲染 - 可以组合采用「静态生成(预渲染)不需要数据的部分 + 请求时,在客户端 js 请求拿到数据后再渲染」
五、API Routes - 在 Nextjs 中创建后端 API 的方式
- 原理:Nextjs 的路由系统 API Routes,文件名就是路由路径的一部分
- 客户端向服务端发起这个路径的请求时,Nextjs 就自动调取这个文件来处理请求
- 语法:文件中导出一个默认函数,接收两个参数
- req - 请求对象,包含方法、头部信息、查询参数、请求体等
- res - 响应对象,可以设置请求状态码、头部信息、响应体等
- 迭代:采用
src/app
的路由方式后,API Routes 的文件也从pages/api
转移到src/app/api
- 常见:
src/app/api/user/route.js
定义api/user/
相关路由
- 常见:
export default function handler(req, res) {
res.status(200).json({ msg: 'hello, nextjs' })
}
- 注意事项:不要在 getStaticProps 和 getStaticPaths 中调用 API Route:以为这两个函数都是在预渲染 - 服务端直接执行的,所以可以直接写服务端代码,例如请求数据库等