React组件属性默认值全解析:从defaultProps到解构默认值
给组件写props默认值在React里算得上最基础的技能之一。但如果你在部门里承担组件库维护的工作很快会发现“属性默认值”远没有看起来那么单纯明明给组件写了defaultProps为什么上线后按钮的文案不按预期走为什么React 19升级完函数组件的默认值集体失效为什么有人用||兜底一传false就被吞掉这篇是React系列第三篇我把组件属性默认值从机制到实操完整拆一遍希望你在自己的组件里写出更稳的默认值逻辑也能在面试和代码评审里把这个问题讲透。这篇文章适合三类人看刚学React、准备搞清楚props细节的初学者在写内部组件库、需要给公共组件设计可配置API的开发者以及正在把老项目从React 17/18往新版本迁移的人。内容不绕弯子该贴源码机制就贴源码机制该给结论就给结论你可以直接照着抄。1. 属性默认值是用来解决什么问题的1.1 调用方少写条件组件内部少一次undefined判断先想一个场景你维护一个公共按钮组件业务方有的地方想要大按钮有的地方想要小按钮但大部分地方不关心大小直接用默认的普通尺寸就好。如果没有属性默认值组件内部每次都要写const size props.size || default;这行代码写一次没感觉写十个组件就有点蠢了。更关键的是调用方也难受为了保证组件正常显示业务方得去翻文档把sizedefault补上不然UI错乱。React提供defaultProps的初衷就是让组件自己声明“你没传时我应该长什么样”调用方只需要传关心的差异属性。这就好比点外卖商家把“默认不加辣”写在商品页里你下单时不用每次备注“不要辣”只有想吃辣的人才需要额外说一句。属性默认值就是React里的“默认不加辣”。从代码角度说默认值还顺带解决了渲染分支问题。没有默认值时组件里经常出现这种防御代码const text props.text ?? 确认;如果默认值统一收口在组件入口处业务逻辑里就不需要到处都是判空分支。这对可维护性的提升是实打实的尤其是多人协作的组件库里少一个??就少一次理解成本。1.2 三种默认值实现方式适用阶段不同React生态里出现过三种主流的默认值写法我按时间顺序排一下写法适用组件状态getDefaultProps()React.createClass创建的组件已退出主流React 15.5后被移入独立包defaultProps静态属性或类静态字段class组件旧版函数组件class组件仍推荐函数组件在React 19已移除ES6函数参数默认值解构默认值函数组件目前最推荐React官方也建议优先使用createClass时代的东西现在基本见不到了但偶尔在古董项目里还能看到理解它只是为了读老代码时不懵。真正要掌握的是后两种class组件的defaultProps以及函数组件的解构默认参数。选择哪种主要看你项目的代码风格和React版本。新项目基本都在写函数组件那就直接上解构默认值如果维护的是老式的class组件体系defaultProps依然是最正规的做法。2. 默认值触发的底层机制很多人都搞错了2.1 undefined才是默认值的唯一触发条件我在带新人时常问一个问题父组件传null组件里的默认值会不会生效十个人里有八个人会答“会因为null就是没传”。这是整个React默认值机制里最重要的一个点默认值只在属性值为undefined时才触发null不会触发。React在处理defaultProps时逻辑可以简化成下面这段伪代码function prepareProps(type, rawProps) { const result { ...rawProps }; const defaultProps type.defaultProps; if (defaultProps) { for (const key in defaultProps) { if (result[key] undefined) { result[key] defaultProps[key]; } } } return result; }注意这个循环里的判定条件result[key] undefined。它不是用!key这种真值判断也不是用 null而是严格等于undefined。这意味着子组件没写这个属性读取时得到undefined默认值生效子组件显式传了undefined默认值依旧生效子组件显式传了null默认值不生效属性保持null。为什么React要这么设计因为undefined在JS语义里表示“未提供”而null表示“主动给了个空值”。业务上这两个状态往往有完全不同的含义。比如一个头像组件的src不传undefined说明用户没设置头像组件展示占位图是合理的传null可能意味着“用户明确要隐藏头像”此时你强行换成占位图就错了。如果你自己用{...defaultProps, ...props}这种方式去合并默认值就会有一个隐藏bug当父组件显式传size{undefined}时展开运算符会把defaultProps里的默认值覆盖掉得到undefined。React内部的逐属性判断逻辑不会犯这个错这也说明为什么不要用对象展开来做默认值合并。2.2 ||、??和解构默认值的边界差异实际开发里除了官方默认值机制很多人习惯在组件内部手写兜底逻辑。我见过最多的是这三种// 方式一逻辑或 const size props.size || default; // 方式二空值合并 const size props.size ?? default; // 方式三解构默认值 function Button({ size default }) {}三种写法看着差不多行为差别很大尤其是||堪称暗坑之王。||判断的是真值只要左侧是0、、false、NaN这些falsy值右侧就会被选中。最典型的踩坑场景是布尔属性组件默认按钮可点击父组件传disabled{false}想禁用这个默认行为结果false || true得到true按钮反而变禁用了。这类bug定位起来特别费劲因为代码语法完全没毛病纯粹是语义被运算符扭曲了。??空值合并运算符只针对null和undefined做兜底看起来比||靠谱很多但它仍然和React默认值机制有区别React只兜undefined??把null也一起兜了。所以如果你明确知道父组件可能传null表示“清空这个属性”用??就会破坏这个意图。解构默认值则是在JS语言层面实现“仅当undefined时取默认值”的规则这和React的defaultProps行为完全一致。这也是官方推荐函数组件优先用它的核心原因。三种方式的对照表放在第4.4节排查问题可以直接当速查表用。2.3 null与undefined工程上的分水岭很多业务开发不区分null和undefined觉得“反正都是没有”这种习惯在普通业务代码里也许问题不大但放在组件默认值设计上就是明显的隐患。举一个真实场景。我们内部有个输入框组件value默认值是空串。产品需求是“没有传value时输入框展示占位提示本身内容为空”。后来接口那边要支持“当服务端返回null时清空输入框”前端拿到null直接塞给输入框结果组件判断value不是undefined默认值不生效输入框里显示了个“null”。排查到最后就是null和undefined语义混用的锅。所以我建议在组件设计阶段就把这两个状态的口径定清楚。我的习惯是undefined 调用方未感知这个属性组件用默认值兜底null 调用方主动传了空值组件应尊重这个信号不强行替换。如果你接手的老组件里到处都用||兜底先别急着重构把“哪些属性必须允许数值0、空串和false”梳理出来再逐个替换成解构默认值或??否则很容易改出一堆新bug。3. 实操从老组件到新组件默认值写法怎么演进3.1 类组件里的defaultProps两种写法class组件里写defaultProps有两种等价的姿势类静态字段以及外部赋值。下面这种static写法是现在的标准import React, { Component } from react; import PropTypes from prop-types; class Button extends Component { static defaultProps { size: default, disabled: false, children: 确定 }; render() { const { size, disabled, children } this.props; return ( button className{btn btn-${size}} disabled{disabled} {children} /button ); } } Button.propTypes { size: PropTypes.oneOf([small, default, large]), disabled: PropTypes.bool }; export default Button;如果你维护的项目构建配置还停留在更老的写法也可以用外部赋值的等价形式class Button extends Component { render() { // ... } } Button.defaultProps { size: default, disabled: false, children: 确定 };这两种写法在React内部完全等价static只是语法糖最后都会变成构造函数上的静态属性。需要注意一个优先级用户传入的props始终高于defaultProps。React合并的顺序是先填默认值再覆盖用户传入值所以不存在默认值把用户配置挤掉的可能。配合prop-types做运行时校验时defaultProps还能顺带减轻校验负担——因为默认值填充后多数属性已经不是undefined不会误触发“必填属性缺失”的警告。不过提醒一句prop-types本身只是开发期工具打包上线后不会做运行时校验别把默认值逻辑建立在“propTypes能拦截错误传参”这个假设上。3.2 函数组件推荐用ES6解构默认值函数组件目前最推荐的写法是在解构props的同时给默认值function Button({ size default, disabled false, children 确定, ...rest }) { return ( button className{btn btn-${size}} disabled{disabled} {...rest} {children} /button ); } export default Button;这段代码里的...rest有一点容易忽略解构掉已知属性后剩余属性会被收集到rest里再展开到原生button上。如果忘了收rest组件就吞掉了type、onClick、>function Pagination({ config {} }) { const { pageNum 1, pageSize 10, total 0 } config; // 业务逻辑... }这种嵌套默认值适用于“父组件传了一个对象但对象只填了一部分字段”的场景。注意如果父组件传的是config{null}第一层解构默认值不会生效后面读取config.pageNum会直接抛错。遇到这种不确定外部数据的情况可以先处理一层nullfunction Pagination({ config }) { const { pageNum 1, pageSize 10 } config ?? {}; }3.3 React 18.3警告和React 19移除升级前要做什么函数组件上的defaultProps最近几年一直处于“准备被淘汰”的状态React 17里还能正常用React 18.3开始会打出弃用警告到React 19正式移除。升级之后最直观的变化是函数组件上定义的defaultProps完全不再生效。假设老代码是function Button(props) { return button className{props.size}{props.children}/button; } Button.defaultProps { size: default };在React 19里父组件如果不传sizeprops.size就是undefined页面样式直接崩掉。class组件不受影响但现在新代码基本没人写class了所以这个变化影响的覆盖面非常广。我在迁移老项目时给团队列的检查清单大致是这样的全代码库里搜索.defaultProps逐个确认它挂的是class组件还是函数组件函数组件的defaultProps统一改成解构默认参数如果一个组件同时用了propTypes和defaultProps改默认值写法后重新跑一遍类型检查和组件测试重点回归那些“曾经靠默认值才显示出正确文案”的组件比如按钮文字、空状态占位符、分页每页条数。对组件库作者来说更稳妥的做法是直接对外声明“函数组件请传显式props”内部再做一层兜底转换。但这是治标的过渡方案长期还是要把组件源码切到新的默认值写法上。3.4 高级场景children备用内容、嵌套对象、半受控组件默认值不只服务普通props有几个高级用法很实用建议在真实项目里演练一遍。第一个是children的备用内容。某些展示型组件在没有children时希望能渲染一个“默认插画”或“默认文案”。可以先判断一下children是否为空再取默认function EmptyState({ title 暂无数据, children }) { return ( div classNameempty-state h3{title}/h3 {children ?? p你可以尝试刷新页面或调整筛选条件/p} /div ); }这里如果用children || p...当父组件传children{0}或children时也会被替换成默认内容这就不合理了。用??严格处理“没传children”的情况更安全。第二个是嵌套对象的默认值。很多组件接收一个config对象里面一堆字段。如果config整体可能不传可以先给config本身设默认对象再解构内部字段function Chart({ config {}, ...rest }) { const { showLegend true, showTooltip true, animationDuration 300 } config; // 组装图表... }注意这样写时如果父组件传config{{ showLegend: false }}showLegend会正确保留false不会因为falsy被吞掉。这正是解构默认值比||安全的地方。第三个是半受控组件。有些组件允许业务方不传某个值内部自己维护状态一旦业务方传了就切换到受控模式。比如一个可折叠面板默认展开但允许外部控制function Collapse({ defaultOpen true, open, onToggle }) { const [innerOpen, setInnerOpen] useState(defaultOpen); const isControlled open ! undefined; const isOpen isControlled ? open : innerOpen; const toggle () { if (isControlled) { onToggle?.(!isOpen); } else { setInnerOpen(!isOpen); } }; return ( div className{isOpen ? collapse-open : collapse-closed} button onClick{toggle}切换/button /div ); }这里用open ! undefined判断是否受控配合defaultOpen做非受控初始值是两个默认值协同工作的典型写法。这种模式在很多组件库里都能看到理解了默认值的触发条件半受控组件的行为也就不会踩错了。4. 常见问题排查与避坑实录4.1 HOC直接调用组件函数defaultProps不生效有一种场景很隐蔽自己写的高阶组件HOC在内部直接像普通函数一样调用子组件而不是通过React.createElement或JSX渲染。比如function withLoading(Component) { return function WrappedComponent(props) { if (props.loading) { return Loading /; } return Component(props); // 问题出在这 }; }正常React渲染组件时会先走元素创建流程这个流程会读取Component.defaultProps并填充默认值。但Component(props)这种直接函数调用不会走这一步于是所有默认值在这个HOC里全部失效props就是原始传入的props没传的属性全是undefined。排查时最烦的是脱离HOC单独用组件一切正常一旦套上HOC文案就丢了。解决方式有两种一是HOC内部改成JSX渲染return Component {...props} /二是干脆放弃函数组件的defaultProps改用解构默认值这样即使被直接调用默认值也是语言层面生效的。如果你维护的组件库里有不少HOC建议全局搜一下return [A-Z].*\(这种直接调用组件函数的地方顺手改掉。4.2 propTypes没安装控制台刷一屏错误React 15.5之后PropTypes被移出了React核心包现在需要单独安装npm install prop-types很多老项目从React 16升级到React 17/18时忘了同步装这个包结果组件里用Button.propTypes {...}的地方全变成运行时错误。更要命的是这类错误通常只在开发环境打印上线后静默消失很容易被忽视。我的建议是新项目里尽量用TypeScript做类型约束不用再依赖prop-types但如果团队里还有大量老代码至少把prop-types放进dependencies而不是devDependencies防止CI构建时把开发依赖裁掉导致线上运行时挂掉。此外配合defaultProps时不要在propTypes里把有默认值的属性标成isRequired这会造成“明明有默认值还报缺失”的乌龙。4.3 TS环境下默认值的类型收敛问题TypeScript项目和defaultProps的兼容性是老生常谈。最典型的痛点是写在类静态字段上的defaultProps无法自动影响props的类型推断。你明明定义了size default但业务方使用组件时IDE仍然提示size是可选属性。函数组件用解构默认值就没有这个问题interface ButtonProps { size?: small | default | large; disabled?: boolean; children?: React.ReactNode; } function Button({ size default, disabled false, children 确定 }: ButtonProps) { return ( button className{btn btn-${size}} disabled{disabled} {children} /button ); }这里size的默认值字符串要写类型子集TS就能在组件内部把size收窄成非可选类型。这样组件里后续的逻辑判断更干净也能避免一堆不必要的可选链。如果确实要在class组件里用defaultProps并享受类型收益通常要额外定义Props类型的“默认值版本”type ButtonProps { size?: small | default | large; disabled?: boolean; }; type ButtonDefaultProps { size: small | default | large; disabled: boolean; }; class Button extends ComponentButtonProps { static defaultProps: ButtonDefaultProps { size: default, disabled: false }; }这套写法能用但成本偏高。新项目里我不会推荐。4.4 传值行为速查表排查问题直接抄最后把各种“传值方式 兜底写法”的最终结果整理成一张表方便你排查和评审时直接用。假设默认值是字符串default| 父组件传值 | defaultProps | 解构默认值 |props.size ?? default|props.size || default| | --- | --- | --- | --- | --- | | 不传 |default|default|default|default| |undefined|default|default|default|default| |null|null|null|default|default| |||||default| |0|0|0|0|default| |false|false|false|false|default| |large|large|large|large|large|有几条快速记忆的结论上表中的||是重灾区只要业务里允许属性值为0、空串、false就坚决别用||做props兜底函数组件优先用解构默认值行为和React官方defaultProps完全一致还兼容React 19如果确实需要把null也当成“未设置”用??但要确认这样不会破坏“主动传null表示清空”的业务语义。我个人在实际项目里的习惯是组件API文档里明确区分“可选属性”和“可空属性”。可选属性用解构默认值外部类型上标记为?:可空属性允许null传入组件内部自行决定是显示空态还是过滤掉。这样组件的契约边界非常清楚大家调用时也少了很多互相猜的沟通成本。最后再分享一个小技巧给组件加默认值时顺手在组件上方写一行注释说明哪些属性是“业务敏感”的。比如disabled默认false这件事如果业务方传false是被默认值机制忽略的容易引发混淆注释里点明一句“传false不会触发默认传undefined才会”后面维护的人能少走很多弯路。默认值这个东西写对一次不难难的是让团队所有人在同一条规则上理解它。

相关新闻

Zint条码库集成指南:链接Zlib与Libpng输出PNG的避坑实践

Zint条码库集成指南:链接Zlib与Libpng输出PNG的避坑实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:28:31 阅读更多 →
Hitrate指标全解读:广告命中率、推荐召回与缓存命中率的区别与优化

Hitrate指标全解读:广告命中率、推荐召回与缓存命中率的区别与优化

“Hitrate”这个单词,放在不同人面前,理解完全不一样。做广告投放的同学会说这是“命中率”,做推荐算法的会说这是“召回命中率”,写后端的则会直接甩给你“缓存命中率”。我在这三个方向都折腾过,第一次被人问“你们H…

2026/10/13 5:28:31 阅读更多 →
AnyPS5技术解析:从模拟器到兼容层的PS5游戏生态移植实践

AnyPS5技术解析:从模拟器到兼容层的PS5游戏生态移植实践

PS5主机发售这几年,硬件层面的话题热度始终没降下来,而“AnyPS5”这类名字在玩家和开发者圈子里出现得越来越频繁。很多人第一反应是问:这名字到底是指一台设备、一套软件,还是一个研究项目?说实话,第一次看…

2026/10/13 5:28:31 阅读更多 →

最新新闻

LaTeX常见问题速查手册:环境配置、中文排版与排错指南

LaTeX常见问题速查手册:环境配置、中文排版与排错指南

1. 这份LaTeX常见问题整理,到底能帮你省下多少时间很多人第一次接触LaTeX,是被导师或编辑部逼的——论文模板发过来,后缀是.tex,打开一看满屏反斜杠,整个人是懵的。我在过去几年里帮同学、同事改过不下几十份LaTeX文稿…

2026/10/13 11:22:41 阅读更多 →
【粤语会议纪要总漏重点?】2026实测6款粤语录音转文字方案,附从收音到归档的完整流程

【粤语会议纪要总漏重点?】2026实测6款粤语录音转文字方案,附从收音到归档的完整流程

一、痛点:粤语会议,难在“听得懂”和“记得全”之间在广东、港澳以及不少海外华人企业里,用粤语开会是再正常不过的事。可一说到会后整理纪要,很多人的反应就是头疼——主讲人语速快,句子里夹着英语单词和普通话词汇&a…

2026/10/13 11:22:41 阅读更多 →
Claude+Codex+Grok三剑客组合:CLI工作流与报错排查实战

Claude+Codex+Grok三剑客组合:CLI工作流与报错排查实战

1. 三剑客组合的底层逻辑:为什么不是简单叠加1.1 从单点工具到工作流闭环的认知转变很多人第一次听到“Claude Codex Grok”这个组合,第一反应是“三个AI工具一起用,不就是多开几个窗口吗”。我一开始也这么想,直到在实际项目里…

2026/10/13 11:22:40 阅读更多 →
PC微信内存配置逆向:禁用自动更新与热键提示的工程化方案

PC微信内存配置逆向:禁用自动更新与热键提示的工程化方案

1. 项目概述:为什么“禁用自动更新和热键冲突提示”值得逆向分析在日常办公与个人使用中,PC微信早已不是单纯的通讯工具,而是一个嵌入工作流的轻量级平台——它承载着文件传输、会议接入、小程序快捷入口甚至部分企业内部系统的跳转功能。但恰…

2026/10/13 11:22:40 阅读更多 →
Android Studio Arctic Fox Windows 安装配置与构建优化实践

Android Studio Arctic Fox Windows 安装配置与构建优化实践

简介:面向Windows 64位平台的Android Studio Arctic Fox(2020.3.1.22,即版本4.3)开发工具完整zip安装包,适合Android应用开发者、Java/Kotlin工程师及需要固定IDE版本的移动端团队使用。压缩包体积922.93MB&#xff0c…

2026/10/13 11:22:40 阅读更多 →
今客CRM PHP源码部署与二次开发实战指南

今客CRM PHP源码部署与二次开发实战指南

简介:今客CRM客户管理系统PHP版v1.2.2是一套开源、可部署的轻量级客户关系管理源码,面向计算机专业学生、PHP初学者及毕业设计开发者,用于学习Web系统架构、CRM业务逻辑实现与前后端协同开发。资源共929个文件,涵盖340个PHP核心逻…

2026/10/13 11:21:39 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →