NextJS 13 知识点整理
1. 动态路由的参数传递
1.1. 单个参数
|- posts
|- [id] # 单个参数
|- page.jsx # 获取传入参数
|- page.jsx
// http://127.0.0.1:3000/posts/1
const PostDetail = ({params}) => {
const id = params.id;
}
1.2. 多个参数
|- posts
|- [...slug] # 使用三个点方式
|- page.jsx # 获取传入参数
|- page.jsx
// http://127.0.0.1:3000/posts/1/2
const PostDetail = ({params}) => {
const post_id = params.slug[0];
const user_id = params.slug[1];
}
1.3. 查询参数
使用 searchParams 获取类似 http://localhost:3000/post/15/2?name=zhangsan
获取里面的查询参数 name
const PostDetail = async ({params, searchParams}) => {
console.log(searchParams.name);
}
2. Rest 风格的 API
NextJS 13 中有个 Route Handler,可实现标准的 Rest,下面主要从几个方面了解如何处理:
- 获取参数,URL 参数、Form 参数、json 体、Rest 参数
- 返回响应的方式
- 跨域、cookie、header
目录不一定是 api,可以是 users 、 products 或者任意你想访问的路径,如 users 则最终的 restful 访问路径是:GET https://xxx.xxx.xxx/users/
2.1. 获取请求参数
export async function GET(request) {
// GET URL参数
const { searchParams } = new URL(request.url);
const id = searchParams.get('id');
// Form提交的参数
const formData = await request.formData();
const name = formData.get('name');
const age = formData.get('age');
console.log('name', name, 'age', age)
// POST json体
const res = await request.json();
console.log(res);
return new Response('Result Content', {
status: 200,
});
}
export async function GET(request, { params }) {
// Rest参数
const id = params.id;
const res = await fetch(`http://jsonplaceholder.typicode.com/users/${id}`, { 'cache': 'no-cache' });
const users = await res.json();
return NextResponse.json(users);
}
2.2. 返回响应方式
export async function GET(request) {
// 使用 NextResponse
const res = await fetch(`http://jsonplaceholder.typicode.com/users/${id}`, { 'cache': 'no-cache' });
const users = await res.json();
return NextResponse.json(users);
// 使用 Response
return new Response('{"status":"ok"}', {
status: 200,
headers: {
'Content-type': 'application/json'
}
})
}
2.3. 跨域、cookie、header
import { cookies, headers } from 'next/headers'
export async function GET(request) {
// 使用 cookie
const cookieStore = cookies()
const token = cookieStore.get('token')
// 使用 header
const headersList = headers()
const referer = headersList.get('referer')
// 跨域
return new Response('success', {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
})
}
3. 表单数据的处理
下面是一个填写表单内容,提交并处理的示例代码,三个知识点:
- 表单提交的基础取值方法
- 使用变量的 json 自动拼装
- 使用
useRef
做表单重置 - NextJS 试验性功能 useFormStatus
'use client'
import React, { useRef } from "react";
import { experimental_useFormStatus as useFormStatus } from 'react-dom'
export default function Home() {
const formRef = useRef();
// 试验性功能,为表单提供一个 pending 的状态
const { pending } = useFormStatus()
async function handleSubmit(formData) {
// get 获取对应值
const username = formData.get('username');
const password = formData.get('password');
// 不需要使用 { 'username': username, 'password': password } 组装
// 使用这种方式会默认生成 key
console.log({username, password});
// 使用 useRef 重制表单
formRef.current.reset();
}
return (
<div>
<form action={handleSubmit} style= ref={formRef}>
<input type="text" name="username" placeholder="username" required />
<input type="password" name="password" placeholder="password" required />
<button type="submit" disabled={pending}>
{ pending ? 'Loading...' : 'Submit' }
</button>
</form>
</div>
)
}
4. 环境变量.env
nextjs 不需要手动安装 dotenv,默认已经集成,且不需要在代码中显示去加载。根路径创建 .env 文件,配置好 key-value,直接使用如下方式获取
const API_KEY = process.env.API_KEY;
console.log(API_KEY);
也可在 next.config.js 中使用配置 key-value 使用,见 next.config.js Options env
5. 图片静态资源
默认图片等静态资源放置在 /public 目录中,使用内置的 Image
标签可自动获取
<image src="/spinner.gif" alt="loading" width="{150}" height="{150}" />
但通常生产环境下,/public 目录中的静态资源往往需要上传到某个 CDN 中以加速请求,减少自身服务器处理耗时,这时需要通过以下几个步骤完成
- next.config.js 新增自定义图片处理配置
- 编写自定义图片处理
在 next.config.js 文件中新增下面配置,告诉 nextjs 针对 Image
需要通过自定义过滤处理一遍在渲染https://fla.cdn.bosyun.com/upload/vod/20230509-1/78502762fea1126dd2c3cf3364f198a3.jpg?imageView2/0/format/webp/q/75
images: {
loader: 'custom',
loaderFile: './app/custom/image.jsx',
},
创建 /app/custom 目录,新增一个 image.jsx 的文件,src 参数就是 Image
标签的 src,渲染时会追加整个 CDN 地址,组成有效的图片路径
export default function cloudinaryLoader({ src }) {
return `https://fla.cdn.bosyun.com/upload/vod/20230509-1/${src}`
}
更多关于图片的处理参看,Image,next.config.js Options images
6. 关于如何调试
NextJS 13 有 Server 与 Client 的特性,某些情况 Server 的调试并不能像如前这样,浏览器打开调试模式,代码增加 debugger
段等等,使用 vscode 启动进行调试是一个好办法,如下:
[.vscode/launch.json]
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev",
"serverReadyAction": {
"pattern": "started server on .+, url: (https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
7. 如何转成PWA
7.1. 创建 manifest.json 文件
在 public
目录创建一个有效的 manifest.json 文件
7.2. 配置 manifest.json 文件
在 app/layout.js
文件中通过 metadata 新增 manifest.json 以及 PWA 其他的配置
export const metadata = {
title: 'Life TimeLine',
description: '只是想做个记录',
viewport: 'width=device-width, initial-scale=1.0',
manifest: '/manifest.json',
themeColor: '#FFFFFF',
};
7.3. 安装 next-pwa 依赖
yarn add next-pwa
# 或者
npm i next-pwa
7.4. 增加pwa忽略文件
安装完 next-pwa,编译后会在 public
目录生成 sw 的 js 文件,不需要提交到 Git 仓库,加到忽略文件 .gitignore 中
**/public/sw.js
**/public/workbox-*.js
**/public/worker-*.js
**/public/sw.js.map
**/public/workbox-*.js.map
**/public/worker-*.js.map
版权所有,本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可。转载请注明出处:https://www.wangjun.dev//2023/07/nextjs-13-question/