新版 Next.js 从入门到入土
本教程用的Next.js 是 13 版本
Next.js 简介
- 完善的React项目,搭建轻松
- 自带数据同步,解决服务端渲染最大难点
- 丰富的插件
- 灵活配置
创建第一个项目
手动创建
初始化
npm init
安装所需要的依赖包
npm install --save react react-don next
增加快捷命令
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","dev": "next","build": "next build","start": "next start"},
创建测试文件
在根目录下创建pages文件夹,并在该文件下创建 index.js
pages 文件夹是Next 规定的,在这个文件夹下写入的文件,Next.js 会自动创建对应的路由
function Index() {return (<div>Halo Next.js</div>)
}export default Index
运行 npm run dev
creact-next-app 脚手架创建Next.js 项目
创建项目
npx create-next-app@latest
第一次创建项目,若没有安装nextjs 会提示是否安装
What is your project named? my-app // 项目名
Would you like to use TypeScript? No / Yes // TypeScript
Would you like to use ESLint? No / Yes // ESLint
Would you like to use Tailwind CSS? No / Yes // Tailwind CSS
Would you like to use `src/` directory? No / Yes // src 作为根目录
Would you like to use App Router? (recommended) No / Yes // 路由
Would you like to customize the default import alias? No / Yes // 自定义默认导入别名
What import alias would you like configured? @/* // 配置什么导入别名
运行 npm run dev
Next.js 的page和component
创建一个新的页面
在page目录下创建 about.js
function About () {return (<div>About nextjs</div>)
}export default About
访问 http://localhost:3000/about
在 Next.js 中,一个 page(页面) 就是一个从 .js、jsx、.ts 或 .tsx 文件导出(export)的 React 组件 ,这些文件存放在 pages 目录下。每个 page(页面)都使用其文件名作为路由(route)
创建二级目录页面
在page目录下创建 home 文件 并在该文件下创建 home.js
function Home () {return (<div>home nextjs</div>)
}export default Home
访问 http://localhost:3000/home/home
Component组件的制作
创建组件
在src目录下创建 components 目录,并在该目录下创建 buttonComponent.js 文件
export default ({children})=><button>{children}</button>
引用
在home.js 引入
import dynamic from 'next/dynamic'const ButtonComponent = dynamic(() => import('@/components/buttonComponent'),
// { ssr: false } // 是否关闭 ssr(服务端渲染) 默认是开启
)
使用
<ButtonComponent>按钮</ButtonComponent>
路由
标签式跳转
在home页面新增两个页面
homeA.js
import React from "react";
import Link from "next/link";const HomeA = () => {return (<><div>我是HomeA 页面</div><div><Link href="/home/home"><div>去Home页面</div></Link></div></>)
}export default HomeA
homeB.js
import React from "react";
import Link from "next/link";const HomeB = () => {return (<><div>我是HomeB 页面</div><div><Link href="/home/home"><div>去Home页面</div></Link></div></>)
}export default HomeB
修改home页面内容
import React from "react"
import Link from "next/link"function Home () {return (<div><div>home nextjs</div><div><Link href="/home/homeA"><div>去homeA页面</div></Link></div><div><Link href="/home/homeB"><div>去homeB页面</div></Link></div></div>)
}export default Home
早期版本 Link标签下是要接上a标签的,当前版本(13.4.19)如果加上a标签会报错
Router模块进行跳转(编程式跳转)
修改home.js页面
import React from "react"
import Router from "next/router"const goHomeA = () => {Router.push('/home/homeA')
}const goHomeB = () => {Router.push('/home/homeB')
}function Home () {return (<div><div>home nextjs</div><div onClick={goHomeA}>去homeA页面</div><div onClick={goHomeB}>去homeB页面</div></div>)
}export default Home
传参与接收
Next.js 只能通过 query 来传递参数
标签式
修改home.js页面
import React from "react"
import Link from "next/link"function Home () {return (<div><div>home nextjs</div><div><Link href="/home/homeA?name=张三&age=18"><div>张三</div></Link></div><div><Link href="/home/homeA?name=李四&age=20"><div>李四</div></Link></div></div>)
}export default Home
修改homeA.js页面
withRouter 是 Next.js 框架的高级组件,用来处理路由用的
import React from "react";
import Link from "next/link";
import { withRouter } from "next/router";function Home () {return (<div><div>home nextjs</div><div><Link href="/home/homeA?name=张三&age=18"><div>写法一</div></Link></div><div><Link href={{pathname: '/home/homeA',query: {name: '李四',age: 20}}}><div>写法二</div></Link></div></div>)
}export default withRouter(HomeA)
编程式
import React from "react"
import Router from "next/router"const goHomeA = () => {Router.push('/home/homeA?name=张三&age=18')
}const goHomeA2 = () => {Router.push({pathname: '/home/homeA',query: {name: '李四',age: 20}})
}function Home () {return (<div><div>home nextjs</div><div onClick={goHomeA}>写法一</div><div onClick={goHomeA2}>写法二</div></div>)
}export default Home
钩子函数
History
import React from "react"
import Router from "next/router"Router.events.on('routeChangeStart', (...args) => {console.log('routeChangeStart -> 路由开始变化', ...args)
})Router.events.on('routeChangeComplete', (...args) => {console.log('routeChangeComplete -> 路由结束变化', ...args)
})Router.events.on("beforeHistoryChange", (...args) => {console.log('beforeHistoryChange -> 在改变浏览器 history 之前触发', ...args)
})Router.events.on('routeChangeError', (...args) => {console.log('routeChangeError -> 跳转发生错误', ...args)
})const goHomeA = () => {Router.push('/home/homeA?name=张三&age=18')
}const goHomeA2 = () => {Router.push({pathname: '/home/homeA',query: {name: '李四',age: 20}})
}function Home () {return (<div><div>home nextjs</div><div onClick={goHomeA}>写法一</div><div onClick={goHomeA2}>写法二</div></div>)
}export default Home
Hash
Router.events.on('hashChangeStart', (...args) => {console.log('hashChangeStart -> 路由开始变化', ...args)
})Router.events.on('hashChangeComplete', (...args) => {console.log('hashChangeComplete -> 路由结束变化', ...args)
})
在getInitialProps中获取远端数据
getInitialProps 是挂在 React 组件上的静态方法
如果你使用的是 Next.js 9.3 或更高版本,我们建议你使用 getStaticProps 或 getServerSideProps 来替代 getInitialProps。
官方推荐的是fetch
fetch 请求
在page目录新建一个request.js 页面
import { withRouter } from "next/router";function Request ({router, data}) {return (<><div>{router.name}</div><div>请求页面 {data} </div></>)
}Request.getInitialProps = async () => {const res = await fetch('https://api.github.com/repos/vercel/next.js')const json = await res.json()console.log(json)return { stars: json.stargazers_count }
}export default withRouter(Request)
index.js
import Router from "next/router"const goRequest = () => {Router.push({pathname: '/request',query: {name: '李四',age: 20}})
}export default function Home() {return (<><div>首页</div><div onClick={goRequest}>去Request页面</div></>)
}
运行页面,可以发现,getInitialProps 会在服务端渲染时执行,也会在客户端渲染时执行
- 当页面通过页面刷新等直接形式访问时,会触发
Nextjs使用服务端渲染的方式返回页面数据
此时 getInitialProps 会在服务端执行,浏览器端不会执行
- 当页面通过浏览器端路由跳转的形式访问时(如浏览器前进后退),该页面渲染不会触发
Nextjs服务端渲染
所以实际上 getInitialProps 方法会根据当前页面渲染时的端侧不同,自主地选择在 Node 端还是 Client 端执行
getStaticProps
getStaticProps 会在每次页面访问时被请求
修改request.js
import { withRouter } from "next/router";function Request ({router, content}) {return (<><div>{router.name}</div><div>请求页面 {content} </div></>)
}export const getStaticProps = async () => {const res = await fetch('https://api.github.com/repos/vercel/next.js')const json = await res.json()console.log(json)return {props: {content: json.stargazers_count}};
};export default withRouter(Request)
getStaticProps是用于在构建时预先执行getInitialProps进行的处理并预先生成静态文件的API。 不会在客户端上运行。 始终在服务器端运行。
getServerSideProps
import { withRouter } from "next/router";function Request ({router, content}) {return (<><div>{router.name}</div><div>请求页面 {content} </div></>)
}export const getServerSideProps = async context => {const res = await fetch('https://api.github.com/repos/vercel/next.js')// if (!res) {// notFound 强制页面跳转到 404// return {// notFound: true// };// redirect 来将页面重定向// return {// redirect: {// destination: '/',// permanent: false// }// };// }const json = await res.json()console.log(json)return {props: {content: json.stargazers_count}};
}export default withRouter(Request)
通过 next.js 的 getServerSideProps,我们在开发中可以很好的协调前后端数据,一些页面初始化数据、页面鉴权可以直接在 getServerSideProps 中进行处理,这样可以大大简化页面逻辑,还保障前后端的统一性。
JSX 编写页面的CSS样式
基础写法
新建style.js 页面
const Style = () => {return (<><div>style 页面</div><div className="base">基础</div><style jsx>{`.base {color: blue;font-size: 16px;margin: 40px;display: block;}`}</style></>)
}export default Style
要注意,style 后面要jsx next.js 会自动加入一个随机类名,这样就防止CSS的全局污染,如上述代码 base 会变成 base-xxxxxx
动态样式
修改style.js 页面
import React, {useState} from "react"const Style = () => {const [color, setColor] = useState('blue')const [fontSize, setFontSize] = useState('16')const [margin, setMargin] = useState('40')const changeColor = () => {setColor(color === 'blue' ? 'red': 'blue')}const changeFontSize = () => {setFontSize(fontSize === '16' ? '20': '16')}const changeMargin = () => {setMargin(margin === '10' ? '40': '10')}return (<><div>style 页面</div><div className="base">基础</div><button onClick={changeColor}>改颜色</button><button onClick={changeFontSize}>改字体大小</button><button onClick={changeMargin}>改边距</button><style jsx>{`.base {color: ${color};font-size: ${fontSize}px;margin: ${margin}px;display: block;}`}</style></>)
}export default Style
模块懒加载
新建 import.js 页面
引入 dayjs 库
npm i dayjs
如果我们在页面直接引入,那它就会以公共库的形式进行打包发布,就算项目第一个页面不使用moment也会进行加载,这就是资源浪费
懒加载引入的第三方库
import.js
import React,{useState} from "react";const Import = () => {const [time, setTime] = useState()const changeTime = async () => {const dayjs = await import('dayjs') setTime(dayjs.default(Date.now()).format('YYYY-MM-DD HH:mm:ss'))}return (<><div>import 页面</div><div>当前时间为:{time}</div><button onClick={changeTime}>获取当前时间</button></>)
}export default Import
可以看到我们是在需要的地方才引入
要注意 使用 default 才能生效
懒加载组件
利用 dynamic 引入组件实现
import dynamic from 'next/dynamic'const ButtonComponent = dynamic(() => import('@/components/buttonComponent'))const Import = () => {return (<><div>import 页面</div><ButtonComponent>按钮</ButtonComponent></>)
}export default Import
自定义组件是懒加载的,只有在jsx里用到<ButtonComponent/>时,才会被加载进来,如果不使用就不会被加载
head 组件
那为了更好的进行SEO优化,可以自己定制<Head>标签
创建header.js页面
Next.js已经把<Head>封装好了,本身就是一个组件,可以直接
import Head from 'next/head'const Header = ()=>{return (<><Head><title> 头部 </title> </Head></>)
}export default Header
Next.js框架下使用Ant Design UI
Ant Design是一款阿里开源的前端组件库
从React的角度来讲,它就是一个组件库,里边封装了开发中最常用的一些组件,让我们可以通过简单的配置就可以使用他们
让Next.js 支持引入CSS文件
首先创建一个 pages/_app.js(如果不存在的话)。 然后import 该 styles.css 文件。
样式表的全局特性
旧版本可以通过 @zeit/next-sass 支持css,这个在新版本中已移除
Next.js 通过 [name].module.css 文件命名约定来支持 CSS 模块
CSS 模块通过自动创建唯一的类名从而将 CSS 限定在局部范围内。 这使您可以在不同文件中使用相同的 CSS 类名,而不必担心冲突。
此行为使 CSS 模块成为包含组件级 CSS 的理想方法。 CSS 模块文件 可以导入(import)到应用程序中的任何位置
不加module next.js框架会误以为是全局样式,会引发冲突报错
import styles from '@/styles/test.module.css'const Ant = () => {return (<><div>Ant 页面</div><p className={styles.default}>测试</p></>)
}export default Ant
支持scss
安装scss
npm install sass
用法与 css一致
import styles from '@/styles/test.module.scss'const Ant = () => {return (<><div>Ant 页面</div><p className={styles.default}>测试</p></>)
}export default Ant
安装 ant
npm install antd --save
引入 ant 并使用
新建react.js 页面
import React from 'react';
import { DatePicker } from 'antd';const App = () => {return <DatePicker />;
};export default App;
babel
为了不让webpack 把整个Ant Design的包都进行打包到生产环境
我们需要你用到 babel
npm install --save babel-plugin-import
在项目根目录建立.babelrc文件
{"presets":["next/babel"], //Next.js的总配置文件,相当于继承了它本身的所有配置"plugins":[ //增加新的插件,这个插件就是让antd可以按需引入,包括CSS["import",{"libraryName":"antd"}]]
}
这样我们使用那个组件就打包那个组件,同样CSS也是按需打包的
Next.js生产环境打包
配置package.json 文件夹
"start": "next start -p 8088"
运行打包
npm run build
运行打包好的文件
npm run start
相关文章:
新版 Next.js 从入门到入土
本教程用的Next.js 是 13 版本 Next.js 简介 完善的React项目,搭建轻松自带数据同步,解决服务端渲染最大难点丰富的插件灵活配置 创建第一个项目 手动创建 初始化 npm init安装所需要的依赖包 npm install --save react react-don next增加快捷命…...
OpenCV(十):图像缩放、翻转、拼接的介绍与使用
目录 (1)图像缩放:resize() (2)图像翻转: flip() (3)图像拼接:hconcat() 和vconcat() (1)图像缩放:resize() 使用 cv2.resize() 函…...
C++ 学习之 构造函数 和 析构函数
前言 总的来说,构造函数负责对象的初始化,而析构函数负责对象的清理和资源释放。它们是C面向对象编程中非常重要的概念,用于管理对象的生命周期,确保对象在创建和销毁时都能够正确地进行初始化和清理。 正文 看代码 class perso…...
加快 MySQL 数据迁移
目录 一、先导 1. 自建目标实例 2. 配置目标主从 二、源导出 1. 生成查询用户权限的SQL语句 2. 生成权限的SQL语句 3. 生成创建非主键索引的SQL语句 4. 导出源库结构 5. 导出源库数据 三、目标导入 1. 目标实例设置 2. 创建用户与权限 3. 处理结构导出文件 4. 导…...
CANalyzer panel
(1205条消息) CAPL 脚本中对信号,系统变量,环境变量的 事件响应_capl programs脚本怎么写信号运算_蚂蚁小兵的博客-CSDN博客 注意环境变量是在工程关联的dbc中创建的;而系统变量是在CANoe工程工具栏的”Environment”下的”System Variables”…...
延迟队列的理解与使用
目录 一、场景引入 二、延迟队列的三种场景 1、死信队列TTL对队列进行延迟 2、创建通用延时消息死信队列 对消息延迟 3、使用rabbitmq的延时队列插件 x-delayed-message使用 父pom文件 pom文件 配置文件 config 生产者 消费者 结果 一、场景引入 我们知道可以通过TT…...
jQuery成功之路——jQuery的DOM操作简单易懂
jQuery的DOM操作 1.jQuery操作内容 jQuery操作内容 1. text() 获取或修改文本内容 类似于 dom.innerText 2. html() 获取或修改html内容 类似 dom.innerHTML 注意: 1. text() 是获取设置所有 2. html() 是获取第一个,设置所有 <!DOCTYPE html> <html lang"zh…...
C++ 学习系列 -- 智能指针 make_shared 与 make_unique
一 make_shared 1.1 make_shared 是什么? c 11 中 引入了智能指针 shared_ptr,以及一个模板函数 make_shared 来生成一个制定类型的 shared_ptr。 1.2 引入 make_shared ,解决了什么问题? make_shared的引入,主…...
贝叶斯神经网络 - 捕捉现实世界的不确定性
贝叶斯神经网络 - 捕捉现实世界的不确定性 Bayesian Neural Networks 生活本质上是不确定性和概率性的,贝叶斯神经网络 (BNN) 旨在捕获和量化这种不确定性 在许多现实世界的应用中,仅仅做出预测是不够的;您还想知道您对该预测的信心有多大。例…...
games101作业1
题目 给定三维下三个点 v0(2.0, 0.0, −2.0), v1(0.0, 2.0, −2.0), v2(−2.0, 0.0, −2.0), 你需要将这三个点的坐标变换为屏幕坐标并在屏幕上绘制出对应的线框三角形 (在代码框架中,我们已经提供了 draw_triangle 函数,所以你只需要去构建变换矩阵即可…...
LeetCode 面试题 02.08. 环路检测
文章目录 一、题目二、C# 题解 一、题目 给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。若环不存在,请返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了…...
【Linux】线程安全-生产者消费者模型
文章目录 生产者消费者模型123规则应用场景优点忙闲不均生产者和消费者解耦支持高并发 代码模拟 生产者消费者模型 123规则 1个线程安全的队列:只要保证先进先出特性的数据结构都可以称为队列 这个队列要保证互斥(就是保证当前只有一个线程对队列进行操…...
优化(2) 2023/09/03
今天重新温习了下clean abap,以前只是偶尔打开看几眼。今天把有些自己不熟悉的地方,重点研究了下。有几个点可以在以后工作使用。这几点可能并不能提升程序效率,但会大大提高代码可读性和代码的可扩展性: 用insert XXX into tabl…...
Swap and Reverse 题解
Swap and Reverse 题面翻译 题目描述 本题共有 t t t 组数据。 给定一个长度为 n n n 的字符串 s s s 和一个整数 k k k, s s s 只包含小写字母,你可以进行若干次操作(可以是零次),具体操作如下: 选…...
单元测试:优雅编写Kotlin单元测试
一、MockK简介 MockK是一款功能强大、易于使用的Kotlin mocking框架。在编写单元测试时,MockK能够帮助我们简化代码、提高测试覆盖率,并改善测试的可维护性。除了基本用法外,MockK还提供了许多额外的功能和灵活的用法,让我们能够…...
深度学习入门教学——卷积神经网络CNN
目录 一、CNN简介 一、输入层 二、卷积层 三、池化层 四、全连接层 一、CNN简介 1、应用领域 检测任务 分类与检索 超分辨率重构 2、卷积网络与传统网咯的区别 传统神经网络和卷积神经网络都是用来提取特征的。神经网络: 可以将其看作是一个二维的。卷积神经…...
【MySQL】MySQL系统变量(system variables)列表(mysqld --verbose --help的结果例)
文章目录 【MySQL】MySQL系统变量(system variables)列表(mysqld --verbose --help的结果例)mysqld --verbose --help的结果例参考 【免责声明】文章仅供学习交流,观点代表个人,与任何公司无关。 编辑|SQL和…...
Python学习之四 数据输入与输出
(一) 脚本编程 前面的章节,组要学习了一些简单的Python编程,使用的是交互式解释器,本章节将开始进行脚本编程。可以使用多种编辑器或者IDE完成编码,主要使用vim。 参考前续小节的写法,我们给a、b分别赋值3和5。 在终端运行程序后发现,没有任何输出。这就是本次我们将要…...
VBA技术资料MF51:VBA_在Excel中突出显示唯一值
【分享成果,随喜正能量】世间万物,因果循环不休,你的善心善行,都可能成为你的善缘善果。每天忆佛念佛,每天都在佛菩萨的加持下生活,自然吉祥如意,法喜充满。 。 我给VBA的定义:VBA是…...
Mqtt学习笔记--交叉编译移植(1)
简述 Mqtt目前在物联网行业的应用比较多,mqtt属于应用层的一个中间件,这个中间件实现消息的订阅发布机制。网上介绍Mqtt的实现原来的比较多,这里不细介绍。 其实在我们之前的产品中,自己也开发的有类似的中间件,除了具…...
科学边缘计算ML硬件可靠性设计:从比特精确验证到精细化容错
1. 项目概述:当科学实验遇上极端数据洪流想象一下,你面前有一台每秒产生数TB数据的超级显微镜,或者一个每时每刻都在进行数十亿次粒子对撞的探测器。这些并非科幻场景,而是高能物理、材料科学等前沿科学领域的日常。海啸般的数据从…...
【AI Agent招聘效能跃迁计划】:为什么92%的HR团队在第3周就放弃?——附可立即上线的MVP验证模板
更多请点击: https://intelliparadigm.com 第一章:AI Agent招聘效能跃迁计划的战略定位与行业悖论 在人才竞争白热化的当下,AI Agent并非招聘流程的“自动化补丁”,而是重构人岗匹配底层逻辑的战略支点。其核心价值不在于替代HR执…...
别再报错‘不在sudoers文件中’了!手把手教你用visudo安全配置CentOS/RHEL用户sudo权限
安全配置Linux系统sudo权限的终极指南当你第一次在终端输入sudo命令时,看到"用户不在sudoers文件中"的提示,那种挫败感每个Linux用户都深有体会。但别急着用chmod修改文件权限——这种"野路子"虽然能快速解决问题,却可能…...
如何用OpenSpeedy实现单机游戏5倍速运行:完整免费加速教程
如何用OpenSpeedy实现单机游戏5倍速运行:完整免费加速教程 【免费下载链接】OpenSpeedy 🎮 An open-source game speed modifier. 项目地址: https://gitcode.com/gh_mirrors/op/OpenSpeedy 还在为游戏卡顿和漫长的等待时间烦恼吗?Ope…...
Unity实现CS级FPS手感的四大底层契约与枪械物理精调
1. 这不是又一个“FPS入门教程”,而是一份被反复验证过的实战路线图很多人点开“Unity FPS教程”时,心里想的是:抄几段代码、拖几个预制体、跑通一个能走能跳的场景,就算交差了。我试过不下二十个标着“完整”“从零开始”的FPS项…...
ARTX实时操作系统任务监控与调试实践
1. 实时任务监控需求解析在嵌入式实时操作系统(RTOS)开发中,任务调度监控是调试复杂系统的关键手段。ARTX-166作为一款面向C166架构的高级实时操作系统,其任务调度机制直接影响系统实时性能。当系统出现响应延迟或死锁时ÿ…...
2026技术复盘:告别“易碎”代码,实在Agent重塑企业自动化底座
在2026年的数字化转型浪潮中,企业对于“提效”的追求已从单纯的工具引入转向深度的架构治理。 曾被寄予厚望的固定规则自动化脚本,在经历了数年的规模化应用后,其弊端正集中爆发。 许多企业发现,那些耗费巨资编写的脚本࿰…...
Oracle EBS关联公司段的设计逻辑和设计哲学
从设计逻辑 → 核心原理 → 完整配置事例 → 业务分录实例 → 常见坑的完整说明,全部围绕 “关联公司段(Intercompany Company Segment)” 在 EBS R12 里的设计与实现,不绕弯一、关联公司段的 “设计核心逻辑”1. 本质定义关联公司…...
【限时解密】Claude 3.5 Sonnet专属编程模式:仅开放给前500家企业的上下文感知补全协议
更多请点击: https://kaifayun.com 第一章:Claude 3.5 Sonnet编程辅助的核心能力边界与适用场景 Claude 3.5 Sonnet 在编程辅助领域展现出显著的推理深度与上下文理解能力,但其本质仍是基于大规模语言模型的生成式系统,不具备实时…...
HarmonyOS 鸿蒙PC平台三方库移植:使用 vcpkg 移植 libzen(ZenLib)
网罗开发(小红书、快手、视频号同名)大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方…...
