next.js v14 从入门到跑路

用next.js也有几天了,也是这么一个边看边用这么一个状态,现在主要使用app router模式,更新下next.js v14 app router模式方面的姿势吧。

区别于前面的pages router, app router虽然也是根据目录结构来划分路由,但是它不再依赖于使用getServerSideProps/getStaticProps在服务器时期去获取数据,在app router模式下只区分服务器组件和客户端组件,且一些在pages路由模式下的方法也无法在app路由下使用。

那现在服务器组件怎么获取数据呢?

nextjs app router现在约定的结构是:

app 目录名 (即路由名,比如名字是home,对用的路径是/home)page.ts 当前页面对应的路由layout.ts layout布局组件loading.ts loading加载动画not-found.ts 404页面api restful api文件夹

每一个目录下至少需要一个page.ts文件,否则访问该路由会报错。而layout布局文件则根据是否需要来创建;loading加载文件相当于suspense里的loading,也就是加载这个路由前的加载动画(Suspense应该是唯一一个能用的react组件了吧在服务器组件里,且suspense不需要指定loaidng了);not-found 404页面,只有app根目录下才需要,其他子路由创建无效;api文件夹是存放restful api文件的地址,同app router,一个文件就是一个路由,且同app router的page.ts,restful只认route.ts文件为当前路由文件。

next.js只区分服务器组件和客户端组件,服务器组件可以是异步的。所以如果我们需要在服务器组件里获取数据,直接await请求就可以了。真的比pages路由里的export function getServerSideProps啥的不要方便太多。比如:

import React from 'react';export default async function Home() {const { data } = await fetch(xxx);...return (<div>...<Child result={data} />...</div>)
}

我们把请求好的数据当成props传给子组件就行了,逻辑是与pages的getServerSideProps是一样的;
但是一定要小心,千万不要在服务器组件里使用任何react的hooks或其他api,连组件的合成事件都不行!

这里补充下RESTFUL api的使用方法!

目录结构:

tips: api文件是在app目录下的。

apilogin route.ts // 访问地址是(/api/login)getGamelist route.ts // 访问地址是(/api/getGamelist)...

前面说了只有当前目录下的route.ts才会被当成路由文件,一个route.ts里可以定义GET/POST/PUT/DELETE等method名称的函数,即每个函数对应请求该接口的method属性的接口,所以可以根据需求来设计对应的方法。
route.ts文件

import { NextResponse, NextRequest } from 'next/server';export function Post(req: NextRequest ) {...return NextResponse.json({...}, {status: 200})
}

补充2:
怎么获取Post请求携带的参数?
NextRequest 这个类型是在Web Request api的基础上继承来的(NextResponse也是同理),在Request基础上拓展更多更好使用的属性或方法,具体可看文档。所以想要获取post请求里的req.body 我们可以看mdn上Request的说明 ,其描述携带参数后body是ReadableStream类型,那我们获取直接json格式化就可以了,注意这是一个异步操作。
例如login下的route.ts是这样的:

import { NextResponse, NextRequest } from 'next/server';export async function Post(req: NextRequest ) {const { token } = (await request.json()) as { token?: string };...return NextResponse.json({...}, {status: 200})
}

这样我们就能拿到body里传过来的token字段了。
使用则直接fetch/xmlHttpRequest请求/api/login

...
const request = new Request('/api/login', {method: 'post',body: JSON.stringify({ token }),
})
fetch(request).then((res) => res.json()).then((res) => {...})

一些个人使用后的发现:

虽然区分服务器组件和客户端组件,但是客户端组件不是说一定在浏览器里动态给你渲染出来,它也是在服务器里给你渲染好的。真正想要在浏览器里渲染你可以使用动态导入并指明不需要ssr;

import dynamic from 'next/dynamic';const Loading = dynamic(() => import('@/components/loading'), { ssr: false });

这个Loading组件就不会在服务器时期渲染了。dynamic不止用来延迟加载组件,也可以延迟加载库。

动态路由怎么定义,同pages路由,凡是[xxx]的文件夹都是对应的动态路由。在app router下是不能使用next/router,因为它是只为pages路由服务的,next.js把路由相关的api封装到了next/navigation里。注意pages路由模式也不能使用next/navigation,这是为app router设计的。

那怎么获取路由参数呢?

import { useParams } from 'next/navigation' 通过useParams来获取当前的路由参数。
const params = useParams() 输出这个params就能看到当前所有的路由参数;
import { useSearchParams } from 'next/navigation' 来获取location.search参数
usePathname 则是获取当前的路由地址
编程式导航则给到了useRouter,这个api跟vue router常用用法基本一致,也是啥push/replace/back(vue是go)
以上几个api都来自next/navigation,需要注意的是这几个都是只能在客户端组件内调用,不能用在服务器组件里。
next/navigation里服务器组件能用的api:
notFound 打开404页面
redirect 重定向到某个页面

其他一些补充(server api):
fetch同样是拓展了Web fetch 方法,现在可以指定cache字段来设置缓存时间,所以fetch方法不需要额外导入。
next/headers暴露的headersapi可以让你获取请求头里的参数,只读。
next/headers暴露的cookies`则可以增删改查cookies。怎么用直接看MDN。

next.js内置的组件

Image

image组件是专门用来处理图像的,它功能是非常强大的。看文档
它支持懒加载图片,支持加载动画,可以是 <今天先这么多吧 ,来活了 我要去码>
支持占位图,动态压缩以及图片加载状态的回调等。
需要注意的是,如果加载的是三方的图片资源,需要在next.config.js里配置三方地址的host信息,否则直接错误。
例如我想要加载img.freepik.com这个网站里的图片资源,那我需要先配置remotePatterns
next.config.js

const nextConfig = {...images: {remotePatterns: [{protocol: 'https', //协议hostname: 'img.freepik.com', //host地址			}],// 如果为 true,则源图像将按原样提供,而不是更改质量、大小或格式。默认为falseunoptimized: true,}...
}

Link

Next.js用于页面导航的组件,实际会渲染成a标签。不过区别于编程式导航,Lilnk组件的导航会默认预加载处理。所以为了体验优化之类的,尽量多用Link导航。

Script

用于加载script脚本的组件,可以配置加载策略strategy 及提供加载状态的回调。

Font

用于加载字体的组件,你可以理解成css @font-face的封装。它可以加载远程字体以及本地字体;
远程字体主要是 google字体,通过搜索到对应的字体直接使用即可,用法拉下来的模板里就有加载谷歌字体的示例(在app/layout.ts里)(要是没翻墙工具的话把加载google字体的代码注销吧,不然可能会运行不起来,因为加载不到字体)。
如果google字体没有,需要用到本地自定义字体的话。

import CunstomFont from 'next/font/local';const csFont = CunstomFont({src: '../assets/fonts/Overlock-Regular.ttf',display: 'swap',
});
// 在需要自定义字体的地方直接添加样式csFont.className 比如我全局都要,那我在body上添加自定义字体的class
...
<body className={csFont.className}> ... </body>

具体用法可以参考官方文档 Font

Next.js使用代理请求

如果因为本地开发的时候跨域 想要使用代理来请求,next.js也是支持的。
在next.config.js里有个字段是rewrites,配置这个字段即可实现代理请求;

// 判断环境
const isProd = ['production'].includes(process.env.NODE_ENV);
// 转发
const rewrites = () => {if (!isProd) {return [{source: '/api/:slug*',destination: process.env.NEXT_PUBLIC_BASEURL,},];} else {return [];}
};
const nextConfig = {...rewrites,...
}

使用直接/api/xxx就行了。
NEXT_PUBLIC_BASEURL 是我配置的环境变量,环境变量这里插一嘴。
只有NEXT_PUBLIC前缀的属性能被浏览器环境获取到,服务器环境则不限制,只要是写在环境变量里的字段都能获取到。

应该没啥要补充的了吧,就酱。

middleware中间件

差点把这个忘了,中间件可以在请求时拦截或者重定向到其他页面;middleware通常位于app目录同级,也就是说src/app,那么middleware就在src/middleware.ts这里。
middleware需要暴露出两个方法出来,一个是

config

export const config = {matcher: '*'
}

config.matcher 是匹配的规则,一般是正则表达式,只有匹配上的才会执行middleware中间件

middleware

import { NextRequest, NextResponse } from 'next/server';
...
export function middleware(req: NextRequest) {...// 中间的逻辑 比如要重定向到别的页面if (xxx) {return NextResponse.redirect(new URL('/abc', req.url))}...return NextResponse.next();
}

只有config.matcher匹配上的请求才会执行middleware

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/831299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“Unite“ > MacOS下很不错的网站转应用App的工具

前言 前不久在浏览mac论坛&#xff0c;无意了解到一款非常好的工具&#xff0c;可以将网站转换为app&#xff0c;考虑到我们现在的主要应用都从本地客户端转成web形式使用&#xff0c;但基于本能的使用习惯&#xff0c;还是希望有个快捷的访问信息&#xff0c;这个应用非常适合…

数组删除元素

数组删除元素 1.利用新的数组 将原数组arr的元素&#xff0c;复制到新数组newArr中&#xff0c;复制过程中将要删除的元素&#xff0c;选择不复制 public class Test01{public static void main(String [] args){String [] arr {"zhangsan","lisi","…

C语言——操作符保姆级教学(含整形提升及算数转换)

操作符 一.操作符的分类二.原码、反码、补码三.移位操作符1.左移操作符&#xff1a;<<2.右移操作符&#xff1a;>> 四.位操作符1.按位与—— &2.按位或—— |3.按位异或—— ^4.按位取反—— ~ 五.逗号表达式六.条件操作符七.操作符的属性&#xff1a;优先级、…

408数据结构-树的基本概念与性质 自学知识点整理

树的定义 树是 n n n&#xff08; n ≥ 0 n≥0 n≥0&#xff09;个结点的有限集。当 n 0 n0 n0时&#xff0c;称为空树。 任意一棵非空树应具有以下特性&#xff1a; 有且仅有一个特定的被称为根的结点&#xff08;根结点&#xff09;。当 n &#xff1e; 1 n&#xff1e;1 …

PotatoPie 4.0 实验教程(32) —— FPGA实现摄像头图像浮雕效果

什么是浮雕效果&#xff1f; 浮雕效果是一种图像处理技术&#xff0c;用于将图像转换为看起来像浮雕一样的效果&#xff0c;给人一种凸起或凹陷的立体感觉&#xff0c;下面第二张图就是图像处理实现浮雕效果。 不过这个图是用Adobe公司的PS人工P图实现的&#xff0c;效果比较…

第一课 自动驾驶概述

1. contents 2. 什么是无人驾驶/自动驾驶 3 智慧出行大智慧 4. 无人驾驶的发展历程

Tracecat:开源 SOAR

Tracecat 是一个面向安全团队的开源自动化平台。 开发人员认为&#xff0c;每个人都应该可以使用安全自动化&#xff0c;特别是人手不足的中小型团队。 核心功能、用户界面和日常工作流程基于一流安全团队的现有最佳实践。 使用专门的人工智能模型来标记、总结和丰富警报。 …

Spark RDD的分区与依赖关系

Spark RDD的分区与依赖关系 RDD分区 RDD&#xff0c;Resiliennt Distributed Datasets&#xff0c;弹性式分布式数据集&#xff0c;是由若干个分区构成的&#xff0c;那么这每一个分区中的数据又是如何产生的呢&#xff1f;这就是RDD分区策略所要解决的问题&#xff0c;下面我…

<Linux> 权限

目录 权限人员相对于文件来说的分类更改权限文件的拥有者与所属组 权限 权限是操作系统用来限制对资源访问的机制&#xff0c;权限一般分为读、写、执行。系统中的每个文件都拥有特定的权限、所属用户及所属组&#xff0c;通过这样的机制来限制哪些用户、哪些组可以对特定文件…

VULHUB复现log4j反序列化漏洞-CVE-2021-44228

本地下载vulhub复现就完了&#xff0c;环境搭建不讲&#xff0c;网上其他文章很好。 访问该环境&#xff1a; POC 构造&#xff08;任选其一&#xff09;&#xff1a; ${jndi:ldap://${sys:java.version}.xxx.dnslog.cn} ${jndi:rmi://${sys:java.version}.xxx.dnslog.cn}我是…

双向链表专题

文章目录 目录1. 双向链表的结构2. 双向链表的实现3. 顺序表和双向链表的优缺点分析 目录 双向链表的结构双向链表的实现顺序表和双向链表的优缺点分析 1. 双向链表的结构 注意&#xff1a; 这⾥的“带头”跟前面我们说的“头节点”是两个概念&#xff0c;带头链表里的头节点…

C#描述-计算机视觉OpenCV(3):重映射

C#描述-计算机视觉OpenCV&#xff08;3&#xff09;&#xff1a;重映射 前言色彩波形图像重映射 前言 C#描述-计算机视觉OpenCV&#xff08;1&#xff09;&#xff1a;基础操作 C#描述-计算机视觉OpenCV&#xff08;2&#xff09;&#xff1a;图像处理 在前文中&#xff0c;描…

UI-Diffuser——使用生成性人工智能的UI原型设计

概述。 移动UI是影响参与度的一个重要因素&#xff0c;例如用户对应用的熟悉程度和使用的便利性。如果你有一个类似的应用程序&#xff0c;你可能会选择一个具有现代、好看的设计的应用程序&#xff0c;而不是一个旧的设计。然而&#xff0c;要从头开始研究什么样的UI最适合应…

Java中使用Redis实现分布式锁的三种方式

1. 导语 随着软件开发领域的不断演进,并发性已经成为一个至关重要的方面,特别是在资源跨多个进程共享的分布式系统中。 在Java中,管理并发性对于确保数据一致性和防止竞态条件至关重要。 Redis作为一个强大的内存数据存储,为在Java应用程序中实现分布式锁提供了一种高效的…

静态库、动态库回顾

回顾一下库相关的知识点&#xff0c;总结备忘一下。在某种情况下&#xff0c;你有了如下的代码&#xff0c;结构如下 //pra.h #include <stdio.h> void test_01(); //pra.c #include "pra.h" void test_01() {printf("xxxxxxx----->%s %s()\n",…

typescript类型检查和原始类型

typescript类型检查和原始类型 类型检查 非严格类型是typescript默认的类型检查模式&#xff0c;在该模式下&#xff0c;类型检查的规则相对轻松&#xff0c;不会对undefined和null值做过多的限制&#xff0c;允许将undefined和null值赋给string类型的变量。进行JavaScript代…

【ChatGPT with Date】使用 ChatGPT 时显示消息时间的插件

文章目录 1. 介绍2. 使用方法2.1 安装 Tampermonkey2.2 安装脚本2.3 使用 3. 配置3.1 时间格式3.2 时间位置 4. 反馈5. 未来计划6. 开源协议7. 供给开发者自定义修改脚本的文档7.1 项目组织架构7.2 定义新的 Component(1) 定义一个新的 Component 类(2) 注册该 Component 7.3 一…

ICode国际青少年编程竞赛- Python-1级训练场-基本操作

ICode国际青少年编程竞赛- Python-1级训练场-基本操作 1、 Dev.step(3)2、 Dev.step(1)3、 Dev.step(7)4、 Dev.step(-1)5、 Dev.step(-5)6、 Dev.step(3) Dev.step(-8)7、 Dev.turnRight() Dev.step(1)8、 Dev.turnLeft() Dev.step(1)9、 Dev.step(4) Dev.tur…

自动找出字符串中有符号数字

需求 代码 class Solution:def myAtoi(self, s: str) -> int:s s.strip() # 删除首尾空格if not s: return 0 # 字符串为空则直接返回res, i, sign 0, 1, 1int_max, int_min, bndry 2 ** 31 - 1, -2 ** 31, 2 ** 31 // 10if s[0…

2024年 Java 面试八股文——SpringMVC篇

目录 1.简单介绍下你对springMVC的理解? 2.说一说SpringMVC的重要组件及其作用 3.SpringMVC的工作原理或流程 4.SpringMVC的优点 5.SpringMVC常用注解 6.SpringMVC和struts2的区别 7.怎么实现SpringMVC拦截器 8.SpringMvc的控制器是不是单例模式&#xff1f;如果是&am…