【实战】十一、看板页面及任务组页面开发(一) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十三)
文章目录
- 一、项目起航:项目初始化与配置
- 二、React 与 Hook 应用:实现项目列表
- 三、TS 应用:JS神助攻 - 强类型
- 四、JWT、用户认证与异步请求
- 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式
- 六、用户体验优化 - 加载中和错误状态处理
- 七、Hook,路由,与 URL 状态管理
- 八、用户选择器与项目编辑功能
- 九、深入React 状态管理与Redux机制
- 十、用 react-query 获取数据,管理缓存
- 十一、看板页面及任务组页面开发
- 1.看板列表开发准备工作
- 2.看板列表初步开发
- 3.添加task, bug 图标
学习内容来源:React + React Hook + TS 最佳实践-慕课网
相对原教程,我在学习开始时(2023.03)采用的是当前最新版本:
项 | 版本 |
---|---|
react & react-dom | ^18.2.0 |
react-router & react-router-dom | ^6.11.2 |
antd | ^4.24.8 |
@commitlint/cli & @commitlint/config-conventional | ^17.4.4 |
eslint-config-prettier | ^8.6.0 |
husky | ^8.0.3 |
lint-staged | ^13.1.2 |
prettier | 2.8.4 |
json-server | 0.17.2 |
craco-less | ^2.0.0 |
@craco/craco | ^7.1.0 |
qs | ^6.11.0 |
dayjs | ^1.11.7 |
react-helmet | ^6.1.0 |
@types/react-helmet | ^6.1.6 |
react-query | ^6.1.0 |
@welldone-software/why-did-you-render | ^7.0.1 |
@emotion/react & @emotion/styled | ^11.10.6 |
具体配置、操作和内容会有差异,“坑”也会有所不同。。。
一、项目起航:项目初始化与配置
- 一、项目起航:项目初始化与配置
二、React 与 Hook 应用:实现项目列表
- 二、React 与 Hook 应用:实现项目列表
三、TS 应用:JS神助攻 - 强类型
- 三、 TS 应用:JS神助攻 - 强类型
四、JWT、用户认证与异步请求
- 四、 JWT、用户认证与异步请求(上)
- 四、 JWT、用户认证与异步请求(下)
五、CSS 其实很简单 - 用 CSS-in-JS 添加样式
- 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(上)
- 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(下)
六、用户体验优化 - 加载中和错误状态处理
- 六、用户体验优化 - 加载中和错误状态处理(上)
- 六、用户体验优化 - 加载中和错误状态处理(中)
- 六、用户体验优化 - 加载中和错误状态处理(下)
七、Hook,路由,与 URL 状态管理
- 七、Hook,路由,与 URL 状态管理(上)
- 七、Hook,路由,与 URL 状态管理(中)
- 七、Hook,路由,与 URL 状态管理(下)
八、用户选择器与项目编辑功能
- 八、用户选择器与项目编辑功能(上)
- 八、用户选择器与项目编辑功能(下)
九、深入React 状态管理与Redux机制
- 九、深入React 状态管理与Redux机制(一)
- 九、深入React 状态管理与Redux机制(二)
- 九、深入React 状态管理与Redux机制(三)
- 九、深入React 状态管理与Redux机制(四)
- 九、深入React 状态管理与Redux机制(五)
十、用 react-query 获取数据,管理缓存
- 十、用 react-query 获取数据,管理缓存(上)
- 十、用 react-query 获取数据,管理缓存(下)
十一、看板页面及任务组页面开发
1.看板列表开发准备工作
之前的项目详情进入看板页的路由有个小问题,点击浏览器返回按钮回不去,原因如下:
- 路由列表是栈结构,每访问一个路由都会
push
一个新路由进去,当点击返回,就会将上一个路由置于栈顶;而进入项目详情页(从'projects'
到'projects/1'
)默认重定向子路由是看板页(projects/1/viewboard
),返回上一个路由时,默认又会重定向到看板页路由。列表栈示例如下: ['projects', 'projects/1', 'projects/1/viewboard']
接下来解决一下这个问题,编辑 src\screens\ProjectDetail\index.tsx
(重定向标签新增属性 replace
,在重定向时直接替换原路由):
...
export const ProjectDetail = () => {return (<div>...<Routes>...<Route index element={<Navigate to="viewboard" replace/>} /></Routes></div>);
};
为了方便后续类型统一调用,将 src\screens\ProjectList\components\List.tsx
中 interface Project
提取到 src\types
目录下
视频中 是用 WebStorm ,博主用的是 VSCode:
- 在需要重构的变量上右击,选择重构(快捷键 Ctrl + Shift + R),选择
Move to a new file
,默认同变量名的文件会创建在当前文件所在同一级目录下,其他引用位置也相应改变,涉及引用位置:src\utils\project.ts
src\screens\ProjectList\components\SearchPanel.tsx
src\screens\ProjectList\components\List.tsx
- 拖动新生成的文件到
src\types
目录下,可以看到其他引用位置也相应改变
- 相关功能文档:TypeScript Programming with Visual Studio Code
src\screens\ProjectList\components\SearchPanel.tsx
中 interface User
也执行同样操作,涉及引用位置:
src\screens\ProjectList\components\SearchPanel.tsx
src\screens\ProjectList\components\List.tsx
src\auth-provider.ts
src\context\auth-context.tsx
src\utils\use-users.ts
看板页还需要以下两个类型,新建一下:
src\types\Viewboard.ts
:
export interface Viewboard {id: number;name: string;projectId: number;
}
src\types\Task.ts
export interface Task {id: number;name: string;projectId: number;processorId: number; // 经办人taskGroupId: number; // 任务组kanbanId: number;typeId: number; // bug or tasknote: string;
}
接下来创建数据请求的 hook:
src\utils\viewboard.ts
:
import { cleanObject } from "utils";
import { useHttp } from "./http";
import { Viewboard } from "types/Viewboard";
import { useQuery } from "react-query";export const useViewboards = (param?: Partial<Viewboard>) => {const client = useHttp();return useQuery<Viewboard[]>(["viewboards", param], () =>client("kanbans", { data: cleanObject(param || {}) }));
};
src\utils\task.ts
:
import { cleanObject } from "utils";
import { useHttp } from "./http";
import { Task } from "types/Task";
import { useQuery } from "react-query";export const useTasks = (param?: Partial<Task>) => {const client = useHttp();return useQuery<Task[]>(["tasks", param], () =>client("tasks", { data: cleanObject(param || {}) }));
};
2.看板列表初步开发
接下来开始开发看板列表,展示需要用到项目数据,可以提取一个从 url
获取 projectId
,再用 id
获取项目数据的 hook
新建 src\screens\ViewBoard\utils.ts
:
import { useLocation } from "react-router"
import { useProject } from "utils/project"export const useProjectIdInUrl = () => {const { pathname } = useLocation()const id = pathname.match(/projects\/(\d+)/)?.[1]return Number(id)
}export const useProjectInUrl = () => useProject(useProjectIdInUrl())export const useViewBoardSearchParams = () => ({projectId: useProjectIdInUrl()})export const useViewBoardQueryKey = () => ['viewboards', useViewBoardSearchParams()]export const useTasksSearchParams = () => ({projectId: useProjectIdInUrl()})export const useTasksQueryKey = () => ['tasks', useTasksSearchParams()]
注意:每一个
useXXXQueryKey
都要确保返回值第一项 与后续列表请求useXXX
中useQuery
的第一个参数保持一致,否则后续增删改都无法正常自动重新请求列表,问题排查比较困难
为看板定制一个展示列组件(任务列表),供每个类型来使用
新建 src\screens\ViewBoard\components\ViewboardCloumn.tsx
:
import { Viewboard } from "types/Viewboard";
import { useTasks } from "utils/task";
import { useTasksSearchParams } from "../utils";export const ViewboardColumn = ({viewboard}:{viewboard: Viewboard}) => {const { data: allTasks } = useTasks(useTasksSearchParams())const tasks = allTasks?.filter(task => task.kanbanId === viewboard.id)return <div><h3>{viewboard.name}</h3>{tasks?.map(task => <div key={task.id}>{task.name}</div>)}</div>
}
编辑 src\screens\ViewBoard\index.tsx
:
import { useDocumentTitle } from "utils";
import { useViewboards } from "utils/viewboard";
import { useProjectInUrl, useViewBoardSearchParams } from "./utils";
import { ViewboardColumn } from "./components/ViewboardCloumn"
import styled from "@emotion/styled";export const ViewBoard = () => {useDocumentTitle('看板列表')const {data: currentProject} = useProjectInUrl()const {data: viewboards, } = useViewboards(useViewBoardSearchParams())return <div><h1>{currentProject?.name}看板</h1><ColumnsContainer>{viewboards?.map(vbd => <ViewboardColumn viewboard={vbd} key={vbd.id}/>)}</ColumnsContainer></div>;
};const ColumnsContainer = styled.div`display: flex;overflow: hidden;margin-right: 2rem;
`
通过代码可知:viewboards.map 后 ViewboardColumn 渲染多次,其中 useTasks 也同时执行多次,但是仔细看浏览器开发者工具可发现,相应请求并没有执行多次,而是只执行了一次,这是因为 react-query 的缓存机制(默认两秒内发送的多个key相同且的参数相同的请求只执行最后一次)
访问看板列表可看到如下内容且三种状态任务横向排列即为正常:
待完成
管理登录界面开发开发中
管理注册界面开发
权限管理界面开发
UI开发
自测已完成
单元测试
性能优化
3.添加task, bug 图标
任务的类型接口并不直接返回,而是只返回一个 typeId,并不能明确标识任务类型,需要单独访问接口来获取具体任务类型
新建 src\types\TaskType.ts
:
export interface TaskType {id: number;name: string;
}
新建 src\utils\task-type.ts
:
import { useHttp } from "./http";
import { useQuery } from "react-query";
import { TaskType } from "types/TaskType";export const useTaskTypes = () => {const client = useHttp();return useQuery<TaskType[]>(["taskTypes"], () =>client("tasks"));
};
将以下两个 svg 文件拷贝到 src\assets
bug.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xlinkHref="http://www.w3.org/1999/xlink"><!-- Generator: Sketch 3.5.2 (25235) - http://www.bohemiancoding.com/sketch --><title>bug</title><desc>Created with Sketch.</desc><defs/><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"><g id="bug" sketch:type="MSArtboardGroup"><g id="Bug" sketch:type="MSLayerGroup" transform="translate(1.000000, 1.000000)"><rect id="Rectangle-36" fill="#E5493A" sketch:type="MSShapeGroup" x="0" y="0" width="14" height="14" rx="2"/><path d="M10,7 C10,8.657 8.657,10 7,10 C5.343,10 4,8.657 4,7 C4,5.343 5.343,4 7,4 C8.657,4 10,5.343 10,7" id="Fill-2" fill="#FFFFFF" sketch:type="MSShapeGroup"/></g></g></g>
</svg>
task.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" width="16px" height="16px" viewBox="0 0 16 16" version="1.1"><!-- Generator: Sketch 3.5.2 (25235) - http://www.bohemiancoding.com/sketch --><title>task</title><desc>Created with Sketch.</desc><defs/><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"><g id="task" sketch:type="MSArtboardGroup"><g id="Task" sketch:type="MSLayerGroup" transform="translate(1.000000, 1.000000)"><rect id="Rectangle-36" fill="#4BADE8" sketch:type="MSShapeGroup" x="0" y="0" width="14" height="14" rx="2"/><g id="Page-1" transform="translate(4.000000, 4.500000)" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" sketch:type="MSShapeGroup"><path d="M2,5 L6,0" id="Stroke-1"/><path d="M2,5 L0,3" id="Stroke-3"/></g></g></g></g>
</svg>
直接使用可能会有如下报错:
Compiled with problems:XERROR in ./src/assets/task.svgModule build failed (from ./node_modules/@svgr/webpack/lib/index.js):
SyntaxError: unknown file: Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can set `throwIfNamespace: false` to bypass this warning.
把
skety:type
这种类型的标签属性改成sketchType
驼峰这样才能被JSX
接受。
- 编译有问题: ./src/assets/bug.svg 中的错误-慕课网
- reactjs - SyntaxError: unknown: Namespace tags are not supported by default - Stack Overflow
源 svg
文件 修改后的源码如下:
- bug.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xlinkHref="http://www.w3.org/1999/xlink" xmlnsSketch="http://www.bohemiancoding.com/sketch/ns"><!-- Generator: Sketch 3.5.2 (25235) - http://www.bohemiancoding.com/sketch --><title>bug</title><desc>Created with Sketch.</desc><defs></defs><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketchType="MSPage"><g id="bug" sketchType="MSArtboardGroup"><g id="Bug" sketchType="MSLayerGroup" transform="translate(1.000000, 1.000000)"><rect id="Rectangle-36" fill="#E5493A" sketchType="MSShapeGroup" x="0" y="0" width="14" height="14" rx="2"></rect><path d="M10,7 C10,8.657 8.657,10 7,10 C5.343,10 4,8.657 4,7 C4,5.343 5.343,4 7,4 C8.657,4 10,5.343 10,7" id="Fill-2" fill="#FFFFFF" sketchType="MSShapeGroup"></path></g></g></g>
</svg>
- task.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg"xmlnsSketch="http://www.bohemiancoding.com/sketch/ns"><!-- Generator: Sketch 3.5.2 (25235) - http://www.bohemiancoding.com/sketch --><title>task</title><desc>Created with Sketch.</desc><defs></defs><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketchType="MSPage"><g id="task" sketchType="MSArtboardGroup"><g id="Task" sketchType="MSLayerGroup" transform="translate(1.000000, 1.000000)"><rect id="Rectangle-36" fill="#4BADE8" sketchType="MSShapeGroup" x="0" y="0" width="14" height="14" rx="2"></rect><g id="Page-1" transform="translate(4.000000, 4.500000)" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" sketchType="MSShapeGroup"><path d="M2,5 L6,0" id="Stroke-1"></path><path d="M2,5 L0,3" id="Stroke-3"></path></g></g></g></g>
</svg>
编辑 src\screens\ViewBoard\components\ViewboardCloumn.tsx
(引入图标,并美化):
import { Viewboard } from "types/Viewboard";
import { useTasks } from "utils/task";
import { useTasksSearchParams } from "../utils";
import { useTaskTypes } from "utils/task-type";
import taskIcon from "assets/task.svg";
import bugIcon from "assets/bug.svg";
import styled from "@emotion/styled";
import { Card } from "antd";const TaskTypeIcon = ({ id }: { id: number }) => {const { data: taskTypes } = useTaskTypes();const name = taskTypes?.find((taskType) => taskType.id === id)?.name;if (!name) {return null;}return <img alt='task-icon' src={name === "task" ? taskIcon : bugIcon} />;
};export const ViewboardColumn = ({ viewboard }: { viewboard: Viewboard }) => {const { data: allTasks } = useTasks(useTasksSearchParams());const tasks = allTasks?.filter((task) => task.kanbanId === viewboard.id);return (<Container><h3>{viewboard.name}</h3><TasksContainer>{tasks?.map((task) => (<Card style={{marginBottom: '0.5rem'}} key={task.id}><div>{task.name}</div><TaskTypeIcon id={task.id} /></Card>))}</TasksContainer></Container>);
};export const Container = styled.div`min-width: 27rem;border-radius: 6px;background-color: rgb(244, 245, 247);display: flex;flex-direction: column;padding: .7rem .7rem 1rem;margin-right: 1.5rem;
`const TasksContainer = styled.div`overflow: scroll;flex: 1;::-webkit-scrollbar {display: none;}
`
查看效果:
部分引用笔记还在草稿阶段,敬请期待。。。
相关文章:

【实战】十一、看板页面及任务组页面开发(一) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十三)
文章目录 一、项目起航:项目初始化与配置二、React 与 Hook 应用:实现项目列表三、TS 应用:JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…...

深入源码分析kubernetes informer机制(三)Resync
[阅读指南] 这是该系列第三篇 基于kubernetes 1.27 stage版本 为了方便阅读,后续所有代码均省略了错误处理及与关注逻辑无关的部分。 文章目录 为什么需要resyncresync做了什么 为什么需要resync 如果看过上一篇,大概能了解,client数据主要通…...

FL Studio 21最新for Windows-21.1.0.3267中文解锁版安装激活教程及更新日志
FL Studio 21最新版本for Windows 21.1.0.3267中文解锁版是最新强大的音乐制作工具。它可以与所有类型的音乐一起创作出令人惊叹的音乐。它提供了一个非常简单且用户友好的集成开发环境(IDE)来工作。这个完整的音乐工作站是由比利时公司 Image-Line 开发…...

HTML详解连载(4)
HTML详解连载(4) 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽CSS定义书写位置示例注意 CSS引入方式内部样式表:学习使用 外部演示表:开发使用代码示例行内样式代码示例 选择器作用基础选择器标签选择器举例特…...

STM32 LL库+STM32CubeMX--点亮板载LED
一、前期准备 硬件:STM32F103C8T6开发板调试工具:DAPLink(本次使用)或USB-TTL开发环境:STM32CubeMX、Keil、Vscode(可选)板载LED:PC13(低电平点亮) 二、STM32CubeMX配置 1.选择芯片型号: 2.配置外设时钟:…...
【HBZ分享】ES的评分score机制的原理
score类型 基础评分boost,默认2.2,逆向文档频率值(IDF):表示该词再文档中(ES中)出现的次数越多,表示越不重要,评分越低关键词在文档中出现的频率(TF):表示该词在文档中出现的频率,频率越高表示…...

函数递归专题(案例超详解一篇讲通透)
函数递归 前言1.递归案例:案例一:取球问题案例二:求斐波那契额数列案例三:函数实现n的k次方案例四:输入一个非负整数,返回组成它的数字之和案例五:元素逆置案例六:实现strlen案例七:…...

leetcode-413. 等差数列划分(java)
等差数列划分 leetcode-413. 等差数列划分题目描述双指针 上期经典算法 leetcode-413. 等差数列划分 难度 - 中等 原题链接 - 等差数列划分 题目描述 如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。 例如࿰…...

从零开始学习 Java:简单易懂的入门指南之MAth、System(十二)
常见API,MAth、System 1 Math类1.1 概述1.2 常见方法1.3 算法小题(质数)1.4 算法小题(自幂数) 2 System类2.1 概述2.2 常见方法 1 Math类 1.1 概述 tips:了解内容 查看API文档,我们可以看到API文档中关于Math类的定义如下: Math类…...

人工智能原理概述 - ChatGPT 背后的故事
大家好,我是比特桃。如果说 2023 年最火的事情是什么,毫无疑问就是由 ChatGPT 所引领的AI浪潮。今年无论是平日的各种媒体、工作中接触到的项目还是生活中大家讨论的热点,都离不开AI。其实对于互联网行业来说,自从深度学习出来后就…...

【Linux】以太网协议——数据链路层
链路层解决的问题 IP拥有将数据跨网络从一台主机送到另一台主机的能力,但IP并不能保证每次都能够将数据可靠的送到对端主机,因此IP需要上层TCP为其提供可靠性保证,比如数据丢包后TCP可以让IP重新发送数据,最终在TCP提供的可靠性机…...
Neo4j之MATCH基础
1】基本匹配和返回:查找所有节点和关系,返回节点的标签和属性。 MATCH (n) RETURN n;2】条件筛选:查找所有名为 "Alice" 的人物节点。 MATCH (person:Person {name: Alice}) RETURN person;3】关系查询:查找所有和 &q…...

Python实验代码合集
NumPy实验(1) NumPy实验(2) NumPy实验(3) SciPy实验(1) 请结合最小二乘法的原理,利用以前学的Numpy和Python知识,实现最小乘法直线拟合的算法,并测试。 请结合梯度下降的原理,利用以前学的Numpy和Python知识,实现梯度下降法求函数最小值的…...
Less和Sass的原理和用法
一、原理 1.1 Less定义:是一种动态的样式语言,使CSS变成一种动态的语言特性,如变量、继承、运算、函数。Less既可以在客户端上面运行(支持IE6以上版本、Webkit、Firefox),也可以在服务端运行(Node.js) 1.2 SaSS定义:是一种动态样式语言&#…...
c# List<T>.Aggregate
List<T>.Aggregate 方法的定义: public TAccumulate Aggregate<TAccumulate>(TAccumulate seed, Func<TAccumulate, T, TAccumulate> func)参数解析如下: TAccumulate seed:初始累积值,也是累积的起始值(默认…...
软件测试常用工具总结(测试管理、单元测试、接口测试、自动化测试、性能测试、负载测试等)
前言 在软件测试的过程中,多多少少都是会接触到一些测试工具,作为辅助测试用的,以提高测试工作的效率,使用好了测试工具,能对测试起到一个很好的作用,同时,有些公司,也会要求掌握一…...
Hadoop组件
前言 Hadoop 是一个能够对大量数据进行分布式处理的软件框架。具有可靠、高效、可伸缩的特点。 HDFS(hadoop分布式文件系统) 是hadoop体系中数据存储管理的基础。他是一个高度容错的系统,能检测和应对硬件故障。 Mapreduce(分…...

jeecg-boot批量导入问题注意事项
现象: 由于批量导入数据速度很快, 因为数据库中的create time字段的时间可能一样,并且jeecg框架自带的是根据生成时间排序, 因此在前端翻页查询的时候,数据每次排序可能会不一样, 会出现第一页已经出现过一…...
Django图书商城系统实战开发 - 实现会员管理
Django图书商城系统实战开发 - 实现会员管理 在Django图书商城系统中,会员管理是一个重要的功能模块。该模块包括会员信息的展示、编辑和删除等功能。以下是实现会员管理功能的详细步骤和代码示例。 步骤一:设计数据库模型 首先,我们需要设…...
Kafka如何解决消息丢失的问题
在 Kafka 的整个架构中可以总结出消息有三次传递的过程: Producer 端发送消息给 Broker 端Broker 将消息进行并持久化数据Consumer 端从 Broker 将消息拉取并进行消费 在以上这三步中每一步都可能会出现丢失数据的情况, 那么 Kafka 到底在什么情况下才…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...