【Next.js】002-路由篇|App Router
【Next.js】002-路由篇|App Router
文章目录
- 【Next.js】002-路由篇|App Router
- 一、前言
- 二、文件系统(file-system)
- 1、说明
- 2、演练
- 创建代码
- 运行访问
- 让 Cursor 分析错误
- 别偷懒,还是探究一下 Pages Router 方式吧
- 创建代码
- 运行并访问项目
- /about 路径
- 三、从 Pages Router 到 App Router
- 四、使用 App Router
- 1、定义路由
- 2、定义页面(Pages)
- 说明
- 演练
- 代码修改
- 运行访问
- 3、定义布局(Layouts)
- 说明
- 演练
- 代码修改
- 运行访问
- 嵌套布局
- 代码修改
- 运行访问
- 让 Cursor 分析错误
- 修复后
- 根布局(Root Layout)
- 4、定义模板(Templates)
- 说明
- 演练
- 代码修改
- 运行访问
- 5、布局 VS 模板
- 状态保持
- 渲染行为
- 使用场景
- 代码结构
- 6、定义加载界面(Loading UI)
- 说明
- 演练
- 代码修改
- 运行访问
- 基本原理
- 代码修改
- 访问测试
- 7、定义错误处理(Error Handling)
- 说明
- 演练
- 代码修改
- 运行访问
- 8、定义 404 页面
- 说明
- 运行访问
- 五、参考链接
一、前言
路由(Router)是 Next.js 应用的重要组成部分。在 Next.js 中,路由决定了一个页面如何渲染或者一个请求该如何返回。
Next.js 有两套路由解决方案,之前的方案称之为“Pages Router”,目前的方案称之为“App Router”,两套方案目前是兼容的,都可以在 Next.js 中使用。
从 v13.4 起,App Router 已成为默认的路由方案,新的 Next.js 项目建议使用 App Router。
本篇我们会学习 App Router 下路由的定义方式和常见的文件约定。
二、文件系统(file-system)
1、说明
Next.js 的路由基于的是文件系统,也就是说,一个文件就可以是一个路由。举个例子,你在 pages
目录下创建一个 index.js
文件,它会直接映射到 /
路由地址:
// pages/index.js
import React from 'react'
export default () => <h1>Hello world</h1>
在 pages
目录下创建一个 about.js
文件,它会直接映射到 /about
路由地址:
// pages/about.js
import React from 'react'
export default () => <h1>About us</h1>
2、演练
创建代码
运行访问
让 Cursor 分析错误
回答:这个错误的原因是:你的项目中同时使用了 Next.js 的 App Router(新路由系统)和 Pages Router(传统路由系统)来处理根路径"/",这会导致路由冲突。
Next.js 13+ 版本引入了 App Router,但它不能与 Pages Router 混用于相同的路径。我们需要选择其中一种路由系统。
上面是 Pages Router 的方式,我们现在使用新的 App Router 方式,暂时不再对 Pages Router 方式深究。
别偷懒,还是探究一下 Pages Router 方式吧
创建代码
运行并访问项目
/about 路径
三、从 Pages Router 到 App Router
现在你打开使用 create-next-app
创建的项目,你会发现默认并没有 pages
这个目录。查看 packages.json
中的 Next.js 版本,如果版本号大于 13.4
,那就对了!
Next.js 从 v13 起就使用了新的路由模式 —— App Router。之前的路由模式我们称之为“Pages Router”,为保持渐进式更新,依然存在。从 v13.4 起,App Router 正式进入稳定化阶段,App Router 功能更强、性能更好、代码组织更灵活,以后就让我们使用新的路由模式吧!
可是这俩到底有啥区别呢?Next.js 又为什么升级到 App Router 呢?知其然知其所以然,让我们简单追溯一下。以前我们声明一个路由,只用在 pages
目录下创建一个文件就可以了,以前的目录结构类似于:
└── pages├── index.js├── about.js└── more.js
这种方式有一个弊端,那就是 pages
目录的所有 js 文件都会被当成路由文件,这就导致比如组件不能写在 pages
目录下,这就不符合开发者的使用习惯。(当然 Pages Router 还有很多其他的问题,只不过目前我们介绍的内容还太少,为了不增加大家的理解成本,就不多说了)
升级为新的 App Router 后,现在的目录结构类似于:
src/
└── app├── page.js ├── layout.js├── template.js├── loading.js├── error.js└── not-found.js├── about│ └── page.js└── more└── page.js
使用新的模式后,你会发现 app
下多了很多文件。这些文件的名字并不是我乱起的,而是 Next.js 约定的一些特殊文件。从这些文件的名称中你也可以了解文件实现的功能,比如布局(layout.js)、模板(template.js)、加载状态(loading.js)、错误处理(error.js)、404(not-found.js)等。
简单的来说,App Router 制定了更加完善的规范,使代码更好被组织和管理。至于这些文件具体的功能和介绍,不要着急,本篇我们会慢慢展开。
四、使用 App Router
1、定义路由
文件夹被用来定义路由。 每个文件夹都代表一个对应到 URL 片段的路由片段。**创建嵌套的路由,只需要创建嵌套的文件夹。**举个例子,下图的 app/dashboard/settings
目录对应的路由地址就是 /dashboard/settings
:
2、定义页面(Pages)
说明
那如何保证这个路由可以被访问呢?你需要创建一个特殊的名为 page.js
的文件。至于为什么叫 page.js
呢?除了 page
有“页面”这个含义之外,你可以理解为这是一种约定或者规范。(如果你是 Next.js 的开发者,你也可以约定为 index.js
甚至 yayu.js
!)
在上图这个例子中:
app/page.js
对应路由/
app/dashboard/page.js
对应路由/dashboard
app/dashboard/settings/page.js
对应路由/dashboard/settings
analytics
目录下因为没有page.js
文件,所以没有对应的路由。这个文件可以被用于存放组件、样式表、图片或者其他文件。
当然不止 .js
文件,Next.js 默认是支持 React、TypeScript 的,所以 .js
、.jsx
、.tsx
都是可以的。
那 page.js
的代码该如何写呢?最常见的是展示 UI,比如:
// app/page.js
export default function Page() {return <h1>Hello, Next.js!</h1>
}
演练
代码修改
运行访问
3、定义布局(Layouts)
说明
布局是指多个页面共享的 UI。在导航的时候,布局会保留状态、保持可交互性并且不会重新渲染(解决性能啊),比如用来实现后台管理系统的侧边导航栏。
定义一个布局,你需要新建一个名为 layout.js
的文件,该文件默认导出一个 React 组件,该组件应接收一个 children
prop,chidren
表示子布局(如果有的话)或者子页面。
举个例子,我们新建目录和文件如下图所示:
相关代码如下:
// app/dashboard/layout.js
export default function DashboardLayout({children,
}) {return (<section><nav>nav</nav>{children}</section>)
}
演练
代码修改
运行访问
嵌套布局
代码修改
运行访问
让 Cursor 分析错误
# 分析结果
布局文件重复问题
你在 app/about/layout.js 和 app/layout.js 中都定义了 RootLayout,这会导致布局嵌套和冲突。在 Next.js 中:
app/layout.js 是根布局,应用于所有页面
app/about/layout.js 应该只定义 about 路径下特有的布局# 说明
app/layout.js 是根布局,应用于所有页面,使用 RootLayout;
app/about/layout.js 应该只定义 about 路径下特有的布局,使用 AboutLayout 。
修复后
注意:下面的写法有一处错误,应遵循:根布局必须包含
html
和body
标签,其他布局不能包含这些标签。后面学到模板我才发现这里写错了!
根布局(Root Layout)
布局支持嵌套,最顶层的布局我们称之为根布局(Root Layout),也就是 app/layout.js
。它会应用于所有的路由。除此之外,这个布局还有点特殊。
使用 create-next-app
默认创建的 layout.js
代码如下:
// app/layout.js
import './globals.css'
import { Inter } from 'next/font/google'const inter = Inter({ subsets: ['latin'] })export const metadata = {title: 'Create Next App',description: 'Generated by create next app',
}export default function RootLayout({ children }) {return (<html lang="en"><body className={inter.className}>{children}</body></html>)
}
其中:
app
目录必须包含根布局,也就是app/layout.js
这个文件是必需的。- **根布局必须包含
html
和body
标签,其他布局不能包含这些标签。**如果你要更改这些标签,不推荐直接修改,参考《Metadata 篇》。 - 你可以使用路由组创建多个根布局。
- 默认根布局是服务端组件,且不能设置为客户端组件。
4、定义模板(Templates)
说明
模板类似于布局,它也会传入每个子布局或者页面。但不会像布局那样维持状态。
布局每次不会重新渲染,这样是节省性能的,模板不会维持状态,应该是每次都重新渲染。
模板在路由切换时会为每一个 children 创建一个实例。这就意味着当用户在共享一个模板的路由间跳转的时候,将会重新挂载组件实例,重新创建 DOM 元素,不保留状态。这听起来有点抽象,没有关系,我们先看看模板的写法,再写个 demo 你就明白了。
定义一个模板,你需要新建一个名为 template.js
的文件,该文件默认导出一个 React 组件,该组件接收一个 children
prop。我们写个示例代码。
在 app
目录下新建一个 template.js
文件:
// app/template.js
export default function Template({ children }) {return <div>{children}</div>
}
你会发现,这用法跟布局一模一样。它们最大的区别就是状态的保持。如果同一目录下既有 template.js
也有 layout.js
,最后的输出效果如下:
<Layout>{/* 模板需要给一个唯一的 key */}<Template key={routeParam}>{children}</Template>
</Layout>
也就是说 layout
会包裹 template
,template
又会包裹 page
。
某些情况下,模板会比布局更适合:
- 依赖于 useEffect 和 useState 的功能,比如记录页面访问数(维持状态就不会在路由切换时记录访问数了)、用户反馈表单(每次重新填写)等
- 更改框架的默认行为,举个例子,布局内的 Suspense 只会在布局加载的时候展示一次 fallback UI,当切换页面的时候不会展示。但是使用模板,fallback 会在每次路由切换的时候展示
注:关于模板的适用场景,可以参考《Next.js v14 的模板(template.js)到底有啥用?》,对这两种情况都做了举例说明
演练
代码修改
运行访问
5、布局 VS 模板
布局和模板都是用于在多个页面之间共享 UI 的机制,但它们有一些重要的区别:
状态保持
-
布局 (Layout):
- 在路由切换时会保持状态
- 组件实例会被复用
- 不会重新创建 DOM 元素
- 适合需要保持状态的场景,如导航栏、侧边栏等
-
模板 (Template):
- 在路由切换时不会保持状态
- 每次都会创建新的组件实例
- 会重新创建 DOM 元素
- 适合需要重置状态的场景,如表单、计数器等
渲染行为
-
布局:
- 只在首次加载时渲染一次
- 路由切换时不会重新渲染
- 更节省性能
-
模板:
- 每次路由切换都会重新渲染
- 为每个子路由创建新实例
- 性能开销相对较大
使用场景
-
布局适合:
- 网站的通用结构(导航栏、页脚等)
- 需要保持状态的 UI 组件
- 对性能要求较高的场景
-
模板适合:
- 依赖 useEffect 和 useState 的功能
- 需要在路由切换时重置的功能
- 需要修改框架默认行为的场景(如 Suspense)
代码结构
-
布局:
- 使用 layout.js 文件
- 可以嵌套使用
- 会自动复用已渲染的组件
-
模板:
- 使用 template.js 文件
- 也可以嵌套使用
- 每次都会创建新的组件树
选择使用布局还是模板,主要取决于你的具体需求。如果需要保持状态和提高性能,选择布局;如果需要重置状态和独立实例,选择模板。
6、定义加载界面(Loading UI)
说明
现在我们已经了解了 page.js
、layout.js
、template.js
的功能,然而特殊文件还不止这些。App Router 提供了用于展示加载界面的 loading.js
。
这个功能的实现借助了 React 的Suspense
API。关于 Suspense 的用法,可以查看 《React 之 Suspense》。它实现的效果就是当发生路由变化的时候,立刻展示 fallback UI,等加载完成后,展示数据。
// 在 ProfilePage 组件处于加载阶段时显示 Spinner
<Suspense fallback={<Spinner />}><ProfilePage />
</Suspense>
初次接触 Suspense 这个概念时,很多人会有一个疑问 - “fallback UI 是如何自动关闭的呢?”
虽然 React 官方文档对此没有详细说明,但其实背后的实现原理并不复杂。当组件(如 ProfilePage)在加载数据时,会抛出一个 Promise 对象。Suspense 会捕获这个 Promise,并为其添加一个 then 回调函数。这个回调函数负责将 fallback UI 替换为实际内容。当数据加载完成后,Promise 变为 resolved 状态,then 回调函数执行,从而自动完成 UI 的切换。
理解了这个原理后,让我们来看看如何在项目中使用 loading.js
。首先在 dashboard
目录下创建一个 loading.js
文件:
// app/about/loading.js
export default function AboutLoading() {return <div>Loading about...</div>;
}
演练
代码修改
运行访问
加载中
加载完成
基本原理
就是这么简单。其关键在于 page.js
导出了一个 async 函数。
loading.js
的实现原理是将 page.js
和下面的 children 用 <Suspense>
包裹。因为page.js
导出一个 async 函数,Suspense 得以捕获数据加载的 promise,借此实现了 loading 组件的关闭。
当然实现 loading 效果,不一定非导出一个 async 函数。也可以借助 React 的 use 函数。
代码修改
顺便去掉了:React.Profiler
// app/about/page.js
'use client';
import React, { use } from "react";// 模拟获取数据的异步函数
async function getData() {// 延迟3秒模拟网络请求await new Promise((resolve) => setTimeout(resolve, 3000));return {message: '这是About页面!',author: '訾博', time: '2024年12月28日 12点01分'};
}// 使用 use 函数来处理异步数据
export default function Page() {// use 函数会自动处理 Promise,无需使用 awaitconst data = use(getData());return (<div><h1>{data.message}</h1><h1>{data.author} {data.time}</h1></div>);
}
访问测试
上面是针对 /about
单独实现一个 loading 效果,如果想实现全局的,那就在 app
目录下再写一个 loading.js
即可(不再演示)。
如果同一文件夹既有 layout.js
又有 template.js
又有 loading.js
,那它们的层级关系是怎样呢?
对于这些特殊文件的层级问题,直接一张图搞定:
7、定义错误处理(Error Handling)
说明
文件 error.js
。顾名思义,用来创建发生错误时的展示 UI。
其实现借助了 React 的 Error Boundary 功能。简单来说,就是给 page.js 和 children 包了一层 ErrorBoundary
。
代码示例
前面的代码嵌套太多,太复杂,现对代码进行了简化!
'use client' // 错误组件必须是客户端组件
// dashboard/error.js
import { useEffect } from 'react'export default function Error({ error, reset }) {useEffect(() => {console.error(error)}, [error])return (<div><h2>Something went wrong!</h2><buttononClick={// 尝试恢复() => reset()}>Try again</button></div>)
}
为触发 Error 错误,同级 page.js
的代码如下:
"use client";
// dashboard/page.js
import React from "react";export default function Page() {const [error, setError] = React.useState(false);const handleGetError = () => {setError(true);};return (<>{error ? Error() : <button onClick={handleGetError}>Get Error</button>}</>);
}
让我们回顾一下层级问题:
从这张图里你会发现一个问题:因为 Layout
和 Template
在 ErrorBoundary
外面,这说明错误边界不能捕获同级的 layout.js
或者 template.js
中的错误。如果你想捕获特定布局或者模板中的错误,那就需要在父级的 error.js
里进行捕获。
那问题来了,如果已经到了顶层,就比如根布局中的错误如何捕获呢?为了解决这个问题,Next.js 提供了 global-error.js
文件,使用它时,需要将其放在 app
目录下。
global-error.js
会包裹整个应用,而且当它触发的时候,它会替换掉根布局的内容。所以,global-error.js
中也要定义 <html>
和 <body>
标签。
global-error.js
示例代码如下:
'use client'
// app/global-error.js
export default function GlobalError({ error, reset }) {return (<html><body><h2>Something went wrong!</h2><button onClick={() => reset()}>Try again</button></body></html>)
}
注:global-error.js
用来处理根布局和根模板中的错误,app/error.js
建议还是要写的。
演练
代码修改
运行访问
8、定义 404 页面
说明
最后再讲一个特殊文件 —— not-found.js
。顾名思义,当该路由不存在的时候展示的内容。
Next.js 项目默认的 not-found 效果如下:
如果你要替换这个效果,只需要在 app
目录下新建一个 not-found.js
,代码示例如下:
import Link from "next/link";export default function NotFound() {return (<div><h2>页面未找到</h2><p>无法找到您请求的资源</p><Link href="/">返回首页</Link></div>);
}
运行访问
五、参考链接
- Routers - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
- Building Your Application: Routing
- Routing: Defining Routes
- Routing: Pages and Layouts
- Routing: Loading UI and Streaming
- Routing: Error Handling
- File Conventions: not-found.js
- Functions: notFound
相关文章:

【Next.js】002-路由篇|App Router
【Next.js】002-路由篇|App Router 文章目录 【Next.js】002-路由篇|App Router一、前言二、文件系统(file-system)1、说明2、演练创建代码运行访问让 Cursor 分析错误别偷懒,还是探究一下 Pages Router 方式吧创建代码运行并访问项目/about …...

如何在 Ubuntu 22.04 上使用 systemctl 管理 systemd 服务教程
简介 Systemd 是许多现代 Linux 发行版提供核心功能的默认服务管理器,而 systemctl 是用户与 systemd 服务交互的方式。这使得 systemctl 成为 Linux 管理员工具箱中重要的一部分。 在本文中,我们将探讨如何使用 systemctl 在使用 systemd 的系统上执行…...

Springboot关于格式化记录
日期格式化 返回前端日期需要格式化 <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.2</version> </dependency>JsonFormat(pattern "yyyy-MM-dd…...
Android 自定义shell命令
模拟触摸、按键等操作,直接在命令行输入对应命令即可。命令行如何识别并操作此命令,执行操作的是shell程序,还是java程序?是不是可以添加自定义的命令? 以下在Android13的代码中分析input命令 Android系统中使用了一…...

Unity游戏环境交互系统
概述 交互功能使用同一个按钮或按钮列表,在不同情况下显示不同的内容,按下执行不同的操作。 按选项个数分类 环境交互系统可分为两种,单选项交互,一般使用射线检测;多选项交互,一般使用范围检测。第一人…...

TOP K问题:利用堆排序找出数组中最小的k个数
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。 找小的数需要建大堆来解决,首先将数组中前K个数建成一个大堆,将从k1个数直到数组结束的所有数与堆顶的数进行比较,如果比堆顶的数小,则替换堆顶的数…...
《信息传播:人工智能助力驱散虚假信息阴霾》
在信息爆炸的时代,虚假信息和谣言如同脱缰野马,肆意传播,对社会秩序和公众生活造成了严重影响。人工智能作为一种强大的技术工具,正逐渐成为信息传播的有力助手,为防止虚假信息和谣言扩散提供了新的途径。 虚假信息和…...
数据权限和角色权限区别
1、概念 角色权限(Role-Based Access Control, RBAC)和数据权限(Data Access Control)是两种不同的权限管理策略,它们在权限控制的侧重点和应用场景上有所区别: 角色权限(RBACÿ…...
Flink的多流转换(分流-侧输出流、合流-union、connect、join)
在实际应用中,我们可能要将多个不同来源的数据连接合并在一起进行处理,也有可能要将一条流拆分成多条流进行处理,这就涉及到了Flink的多流转换问题。简单来说,就是分流和合流两大操作,分流主要通过侧输出流实现&#x…...
DirectUI属性表
<?xml version"1.0" encoding"UTF-8"?> <Controls><Window parent""><Attribute name"size" default"0,0" type"SIZE" comment"窗口的初始化大小,如(800,600)"/><Attribu…...

RBAC权限控制
1、Spring Security 是一个功能强大的Java安全框架,它提供了全面的安全认证和授权的支持。 2 SpringSecurity配置类(源码逐行解析) Spring Security的配置类是实现安全控制的核心部分 开启Spring Security各种功能,以确保Web应…...
STM32高级物联网通信之以太网通讯
目录 以太网通讯基础知识 什么是以太网 互联网和以太网的区别 1)概念与范围 (1)互联网 (2)以太网 2)技术特点 (1)互联网 (2)以太网 3)应用场景 (1)互联网 (2)以太网 以太网的层次 1)物理层 2)数据链路层 OSI 7层模型 TCPIP 4层模型 一些常见…...

【小程序】全局配置window和tabBar
目录 全局配置 1. 全局配置文件及常用的配置项 全局配置 - window 1. 小程序窗口的组成部分 2. 了解 window 节点常用的配置项 编辑 3. 设置导航栏的标题 4. 设置导航栏的背景色 5. 设置导航栏的标题颜色 6. 全局开启下拉刷新功能 7. 设置下拉刷新时窗口的背景色 …...

详解VHDL如何编写Testbench
1.概述 仿真测试平台文件(Testbench)是可以用来验证所设计的硬件模型正确性的 VHDL模型,它为所测试的元件提供了激励信号,可以以波形的方式显示仿真结果或把测试结果存储到文件中。这里所说的激励信号可以直接集成在测试平台文件中,也可以从…...

冥想的实践
这是我某一天的正念和冥想实践,我对正念练习、冥想练习进行了分别的统计。 正念练习:1分钟**5次 冥想:15分钟10分钟 正念练习,基本在工作休息时间练习。当然,工作过程中,也有一部分时间会有正念的状态&am…...

STM32F103RCT6学习之四:定时器
1.基础 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、…...

如何在网页端使用 IDE 高效地阅读 GitHub 源码?
如何在网页端使用 IDE 高效地阅读 GitHub 源码? 前言什么是 GitHub1s?使用 GitHub1s 阅读 browser-use 项目源码步骤 1: 打开 GitHub 项目页面步骤 2: 修改 URL 使用 GitHub1s步骤 3: 浏览文件结构步骤 4: 使用代码高亮和智能补全功能步骤 5: 快速跳转和…...

易基因: BS+ChIP-seq揭示DNA甲基化调控非编码RNA(VIM-AS1)抑制肿瘤侵袭性|Exp Mol Med
大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 肝细胞癌(hepatocellular carcinoma,HCC)早期复发仍然是一个具有挑战性的领域,其中涉及的机制尚未完全被理解。尽管微血管侵犯(…...

欢迪迈手机商城设计与实现基于(代码+数据库+LW)
摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本欢迪迈手机商城就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息…...
数据库基础与应用:从概念到实践
数据库是信息技术中的核心组件之一,是现代计算机系统中不可或缺的部分。无论是日常应用的社交网络、电子商务网站,还是企业级的大型系统,几乎所有的信息管理都离不开数据库。那么,数据库究竟是什么?它是如何工作的&…...

当SAP系统内计划订单转换为生产订单时发生了什么?
【SAP系统研究】 #SAP #计划订单 #生产订单 #采购申请 一、关于计划订单的一点疑惑 曾经对SAP为什么会有计划订单,是感到很疑惑的。 这个界面简单,配置点也不多,能被随意“摆布”,一旦要变形就消失得无影无踪的计划订单,why? 但是,再次重新审视过之后,才发现它其实…...
Shell编程核心符号与格式化操作详解
Shell编程作为Linux系统管理和自动化运维的核心技能,掌握其常用符号和格式化操作是提升脚本开发效率的关键。本文将深入解析Shell中重定向、管道符、EOF、输入输出格式化等核心概念,并通过丰富的实践案例帮助读者掌握这些重要技能。 一、信息传递与重定…...

yolov11与双目测距结合,实现目标的识别和定位测距(onnx版本)
一、yolov11双目测距基本流程 yolov11 双目测距的大致流程就是: 双目标定 --> 立体校正(含消除畸变) --> 立体匹配 --> 视差计算 --> 深度计算(3D坐标)计算 --> 目标检测 --> 目标距离计算及可视化 下面将分别阐述每…...
CppCon 2015 学习:Intro to the C++ Object Model
这段代码展示了使用 make 工具来编译 C 程序的简单过程。 代码和步骤解析: C 代码(intro.cpp):#include <iostream> int main() { std::cout<<"hello world\n"; } 这是一个简单的 C 程序,它包…...
AI编程提示词
你是 IDE 的 AI 编程助手,遵循核心工作流(研究 -> 构思 -> 计划 -> 执行 -> 评审)用中文协助用户,面向专业程序员,交互应简洁专业,避免不必要解释。[沟通守则] 1. 响应以模式标签 [模式&#…...

Spring事务回滚在系统中的应用
以文章发布为例,介绍Spring事务回滚在系统中的应用 事务回滚的核心概念 事务回滚是数据库管理系统中的关键机制,它确保数据库操作要么全部成功,要么全部失败。在Spring框架中,我们可以通过Transactional注解轻松实现事务管理。 …...

OpenCV计算机视觉实战(10)——形态学操作详解
OpenCV计算机视觉实战(10)——形态学操作详解 0. 前言1. 腐蚀与膨胀1.1 为什么要做腐蚀与膨胀1.2 OpenCV 实现 2. 开运算与闭运算2.1 开运算与闭运算原理2.2 OpenCV 实现 3. 形态学梯度与骨架提取3.1 形态学梯度3.2 骨架提取 小结系列链接 0. 前言 形态…...

数据通信与计算机网络——数字传输
主要内容 数字到数字转换 线路编码 线路编码方案 块编码 扰动 模拟到数字转换 脉冲码调制(PCM) Delta调制(DM) 传输模式 并行传输 串行传输 一、数字到数字转换 将数字数据转换为数字信号涉及三种技术: 线…...
Python入门手册:异常处理
在编程过程中,异常处理是一个非常重要的环节。它可以帮助我们处理程序运行时可能出现的错误和异常情况,确保程序的稳定性和可靠性。Python提供了强大的异常处理机制,使得我们能够优雅地处理各种异常情况。今天,就让我们一起深入学…...
Matlab | matlab中的图像处理详解
MATLAB 图像处理详解 这里写目录标题图像处理 MATLAB 图像处理详解一、图像基础操作1. 图像读写与显示2. 图像信息获取3. 图像类型转换二、图像增强技术1. 对比度调整2. 去噪处理3. 锐化处理三、图像变换1. 几何变换2. 频域变换四、图像分割1. 阈值分割2. 边缘检测3. 区域分割五…...