普通视图
别再只会调 API 了!LangChain.js 才是前端 AI 工程化的真正起点
React/Vue 代理配置全攻略:Vite 与 Webpack 实战指南
回顾计算属性的缓存与监听的触发返回结果
《闭包、RAG与AI面试官:一个前端程序员的奇幻LangChain之旅》
百度一站式全业务智能结算中台
导读
本文深入介绍了百度一站式全业务智能结算中台,其作为公司财务体系核心,支撑多业务线精准分润与资金流转。中台采用通用化、标准化设计,支持广告、补贴、订单等多种结算模式,实现周结与月结灵活管理。通过业务流程标准化、分润模型通用化及账单测算自动化,大幅提升结算效率与准确性,确保数据合规与业务稳健发展。未来,中台将推进全业务线结算立项线上化、数据智能分析,进一步提升数据分析智能化水平,为公司业务发展提供坚实保障。
01 概述
结算中台作为公司财务体系的核心组成部分,承担着多业务线分润计算、结算及资金流转的关键职能。采用通用化、标准化的设计理念,结算中台能够高效支撑公司内数十个业务线的分润需求,确保广告收入、订单收入、内容分发的精准结算,为公司的财务健康与业务稳健发展提供坚实保障。结算中台建设的核心目标是: 构建高效、标准化、智能化的结算中台体系,支撑多业务线分润计算与资金流转,确保结算数据准确性、高时效披露及业务快速迭代能力,同时降低运维复杂度,推动全业务线结算线上化管理。
结算中台已对接了百家号业务、搜索业务、智能体业务、小说等多个业务线的结算需求, 支持广告分润、补贴分润、订单分润三种结算模式。不同业务线根据各自的业务场景使用不同的结算模式,确保每个业务的收益分配准确无误。结算中台功能分层如图:
![]()
02 基本功能
1. 结算模式
结算中台支持三种结算模式,以适应不同业务场景的结算需求:
-
订单结算:基于直接订单数据,按照订单实际金额与分成策略进行分润计算。
-
补贴结算:针对特定业务或用户群体,提供额外的收益补贴,以增强业务的市场竞争力。
-
广告结算:根据分发内容的广告变现与渠道分成比例,精确计算媒体与内容的实际收益。
2. 结算能力
结算中台支持周结与月结两种结算能力:
-
周结:适用于需要快速资金回笼的业务场景,比如短剧快速回款以后能够再次用于投流, 确保资金流转的高效性。
-
月结:作为默认的结算周期,便于公司进行统一的财务管理与账务处理。
3. 账单测算自动化
结算中台支持重点业务账单自动测算,通过预设的分润模型,自动计算每个渠道、每位作者的应得收益,生成测算报告。这一自动化过程显著提升工作效率,减少人为错误,确保结算数据的绝对准确。
03 需求分析
在推进公司结算业务时,我们致力于实现统一化、标准化,规范业务流程,并确保数据合规化治理,我们面临着诸多问题与挑战,具体表现如下:
1. 流程与规范缺失
-
结算流程管理混乱:存在结算需求未备案即已上线的情况,或者备案内容与实际实现不一致,甚至缺乏备案流程。
-
日志规范陈旧:广告分润场景中,内容日志打点冗余,同时缺少扩展性,导致对新的业务场景无法很好兼容。
2. 烟囱式开发成本高
-
标准化与统一化需求迫切:之前,各个结算业务维护各自的结算系统,涉及不同的技术栈和结算模型,线下、线上结算方式并存,导致人工处理环节多,易出错,case多,管理难度大。为提高效率,需实现结算业务的标准化与统一化,并拓展支持多种业务结算模式。
-
分润模型通用化设计:多数业务结算方式相同,同时账单计算逻辑也相似或者相同,没有必要每个业务设计一套逻辑,需要做通用化设计。
3. 业务迭代中的新诉求
-
测算系统需求凸显:在业务快速迭代的过程中,许多业务希望尽快看到结算效果,以推进项目落地。因此,构建高效的测算系统成为迫切需求,以加速业务迭代和决策过程。
-
提升作者体验:为提升作者等合作伙伴的满意度和忠诚度,结算数据需实现高时效披露,确保他们能及时、准确地获取收益信息。结算账单数据的产出依赖百余条数据源,要保证数据在每天12点前产出,困难重重
-
数据校验与监控机制:结算数据的准确性和质量直接关系到公司的财务健康和业务发展。因此,需建立完善的数据校验和监控机制,确保结算数据的准确无误和高质量。
04 技术实现
根据结算中台建设的核心目标,结合业务痛点,在结算系统建设中,基于通用化、标准化的理念,从以下五个方面来搭建统一的、规范化的结算中台。
-
业务流程标准化:建设一套标准来定义三类结算模式下每个数据处理环节的实现方式,包括业务处理流程、数据处理过程。
-
分润模型通用化:实现不同的账单计算算法,支持各个业务的各类作者收入分配诉求,并且实现参数配置线上化。
-
技术架构统一:统一整个结算业务的技术栈、部署环境、功能入口和数据出口。
-
建设账单测算能力:模拟线上结算流程的账单测算能力,支持业务快速验证分润模型参数调整带来的作者收入影响效果。
-
建设质量保证体系:建设全流程预警机制,通过日志质检、自动对账、数据异常检测来保障账单产出数据时效性、准确性。
1. 业务流程标准化
不同业务场景,采用了通用化、标准化的设计来满足业务的特异性需求,下面是三大结算模式业务流程简图:
![]()
在广告模式、补贴模式、订单模式结算流程设计中, 从日志打点、线上化、计算逻辑等方向考虑了通用化、标准化设计, 具体如下:
(1) 日志打点统一化
统一日志标准, 针对业务日志规范陈旧问题,要求所有接入的业务方严格按照统一格式打点日志,删除冗余字段, 确保数据的规范性与一致性,同时保证设计能够覆盖所有业务场景,为后续处理奠定坚实基础。
针对某些业务定制化的需求, 在广告模式、补贴模式、订单模式三种结算方式中,在设计日志打点规范时, 会预留一些扩展字段, 使用时以 JSON 形式表示, 不使用时打默认值。
(2) 账单计算线上化
在补贴结算模式中,之前不同业务都有各自的账单格式设计,同时存在离线人工计算账单的非规范化场景,账单无法统一在线计算、存储、监管。新的结算中台的补贴结算模式,将所有离线结算模式,使用统一的账单格式,全部实现线上化结算,实现了业务结算流程规范化。
(3) 账单计算逻辑优化
比如在广告模式中,百家号业务的公域视频、图文、动态场景中,由于收入口径调整,迭代效率要求,不再需要进行广告拼接,所以专门对账单计算流程做了优化调整。不仅满足业务诉求,同时做了通用化设计考虑,保证后续其他业务也可以使用这套流程的同时, 也能兼容旧的业务流程。
广告模式结算流程优化前:
![]()
广告模式结算流程优化后:
![]()
2. 分润模型通用化
不同业务场景,不同结算对象,有不同的结算诉求,不仅要满足业务形态多样化要求,还要具有灵活性。因此抽取业务共性做通用性设计,同时通过可插拔式设计灵活满足个性化需求。
![]()
(1) 基于流量变化模型
以合作站点的优质用户投流方为代表的用户,他们在为百度提供海量数据获得收益的同时,也有自己的诉求,那就是自己内容的收益不能受到其他用户内容的影响。自己优质内容不能被其他用户冲淡,当然自己的低质内容也不会去拉低别人的收益水平。
对于此部分用户我们提供“基于流量变现的分润”策略,简单来说就是,某一篇内容的收益仅仅由它自己内容页面挂载的广告消费折算而来,这样就保证了优质用户投流方收益的相对独立,也促使优质用户产出更加多的内容。
(2) 基于内容分发模型
-
部分作者只关注收益回报: 对百家号的某些作者来说,他们的目的很单纯,他们只关注产出的内容是否获得具有竞争力的收益回报,至于收益怎么来他们并不关心。
-
“基于流量变现”策略不妥此时,我们再使用“基于流量变现”的策略的话,就有些不妥,举个极端里的例子,有一个作者比较倒霉,每次分发都没有广告的渲染,那他是不是颗粒无收?这对作者是很不友好的。
-
“基于内容分发的分润”模型: 基于收益平衡性考虑,我们推出了更加适合百家号用户的“基于内容分发的分润”模型。在这种模型下,只要内容有分发,就一定有收益,而不管本身是否有广告消费。
-
策略平衡考虑: 当然,为了防止海量产出低质内容来刷取利润,在分润模型上,我们同时将内容质量分和运营因子作为分润计算的权重,也就是说作者最终的收益由内容的质量和内容的分发量共同决定,以达到通过调整分润来指导内容产出的目的。
(3) 基于作者标签模型
为了实现对百家号头部优质作者进行激励,促进内容生态良性发展, 会对不同的作者进行打标, 并且使用不同的分润模型, 比如对公域的百家号作者进行打标, 优质作者, 通过动态单价及内容质量权重策略来给到他们更加的分成, 其他的普通作者, 通过内容分发模型来分润。这样不仅保证了优质作者取得高收益,也保证了其他作者也有一定的收益
另外,出于对预算的精确控制,发挥每一笔预算的钱效,优质的作者会占用较大的预算资金池,而普通作者使用占用较少的预算资金池。同时也会对每类资金池进行上下限控制,保证预算不会花超。
(4) 基于运营场景模型
为了实现对百家号作者的精细化运营,比如对一些参与各类短期活动的作者给予一定的阶段性的奖励,可以通过补贴模型来实现。在一些运营活动中,需要控制部分作者的分成上限,分润模型会进行多轮分成计算,如果作者的收益未触顶并且资金池还有余额的情况下,会对余额进行二次分配,给作者再分配一些收益。此类模型主要是为了实现灵活多变的作者分润策略。
3. 技术架构统一
根据业务流程标准化、分润模型通用化的设计原则,建设统一的结算中台。以下是结算中台统一结算业务前后的对比:
![]()
![]()
4. 建设账单测算能力
为各个需要测算能力的业务,设计了一套通用的测算流程,如下图:
![]()
针对每个测算业务,设计了独立的测算参数管理后台,用于管理业务相关的分润模型参数,如下图:
![]()
测算流程设计
(1) 功能简述: 每个测算业务, 产品需要登录模型参数管理后台,此后台支持对分润模型参数进行创建、查看、编辑、测算、复制、上线、删除,以及查看测算结果等操作, 出于业务流程合规化的要求, 每次模型参数上线前, 需要对变更的参数完成线上备案流程才可以上线,实现分润流程合规线上化。
(2) 流程简述
-
流程简述概览: 每次测算时, 产品需要先创建一个版本的账单模型测算参数,并发起参数测算,参数状态变成待测算 。
-
离线任务与收益计算: 此后,离线任务会轮询所有的待测算参数,提交Spark任务,调用账单计算模型来计算作者收益,最后生成TDA报告。
-
查看与评估测算报告: 产品在管理平台看到任务状态变成测算完成时, 可以点击 TDA 链接来查看测算报告, 评估是否符合预期。
-
根据预期结果的操作:如果不符合预期,可以编辑参数再次发起测算;如果符合预期,则可以发起备案流程,流程走完后可以提交上线。
(3) 收益明显: 通过账单测算建设, 不仅解决结算需求未备案即已上线或者备案内容与实际实现不一致,甚至缺乏备案流程的业务痛点问题, 而且把业务线下账单计算的流程做到了线上, 做到留痕可追踪。同时也满足了业务高效迭代的诉求, 一次账单测算耗时从半天下降到分钟级, 大大降低了账单测算的人力成本与时间成本。
5. 建设质量保障体系
为了保证业务质量,从以下几方面来建设:
(1) 建设数据预警机制:为保证作者账单数据及时披露, 分润业务涉及的 百余条数据源都签订了 SLA, 每份数据都关联到具体的接口人, 通过如流机器人来监控每个环节的数据到位时间, 并及时发出报警信息, 并推送给具体的接口负责人。对于产出延迟频次高的数据流,会定期拉相关负责人相关复盘,不断优化数据产出时效,保证账单数据在每天如期产出
(2) 数据异常检测机制:对账单数据进行异常波动性检测, 确保数据准确性 ,及时发现并处理潜在异常问题
(3) 自动对账机制:每天自动进行上下游系统间账单明细核对,保证出账数据流转的准确无误。
(4) 日志质检机制:每日例行对日志进行全面质检分析, 及时发现日志打点日志。
05 中台收益
结算中台作为公司财务体系的核心,承担多业务线分润计算与资金流转重任。
(1) 通过通用化、标准化设计,高效支撑数十个业务线的精准结算,确保广告、订单、内容分发的业务结算稳定、健康。近一年,结算业务零事故、零损失。
(2) 中台支持多种结算模式与灵活周期管理,实现账单测算自动化,账单测算时间从天级降到小时级。提升效率并减少错误,提升业务需求迭代效率。
(3) 通过业务流程标准化、分润模型通用化、账单测算能力建设及质量保证体系,解决了结算业务规范缺失、业务形态多样等问题。累计解决历史结算case数十个,涉及结算金额达千万级。
未来,结算中台将推进全业务线结算立项线上化、周结与测算能力落地、项目全生命周期管理,并依托大模型能力实现数据智能分析,进一步提升数据分析智能化水平,为公司业务稳健发展提供坚实保障。
06 未来规划
1、推进全业务线结算实现立项线上化;
2、推进周结 、测算能力在各业务线上落地;
3、推进项目全生命周期管理,实现项目从上线到下线整体生命周期变化线上化存档,可随时回顾复盘。
4、数据智能分析,依托公司大模型能力,实现通过多轮对话问答来进行数据分析,针对业务问题进行答疑解惑,提升数据分析的智能化水平。
JavaScript中的迭代器和生成器
2.2 Node的模块实现
我用 NestJS + Vue3 + Prisma + PostgreSQL 打造了一个企业级 sass 多租户平台
Three.js 入门指南:揭开 3D 网页的魔法面纱
Ant Design 6.0 尝鲜:上手现代化组件开发|得物技术
Next.js第十五章(Image)
nest.js / hono.js 一起学!日志功能/统一返回格式/错误处理
PinK(Cocos4.0?)生成飞机大战,抢先体验全流程!
我如何用 AI 处理历史遗留代码:MiniMax M2.1 升级体验
一、
最近,我写了好几篇 AI 教程,就收到留言,要我谈谈我自己的 AI 编程。
今天就来分享我的 AI 编程,也就是大家说的"氛围编程"(vibe coding)。
![]()
声明一下,我只是 AI 初级用户,不是高手。除了不想藏私,更多是为了抛砖引玉,跟大家交流。
二、
平时,我很少用 AI 生成新项目。因为每次看 AI 产出的代码,我总觉得那是别人的代码,不是我的。
如果整个项目都用 AI 生成,潜意识里,我感觉不到那是自己的项目。我的习惯是,更愿意自己写新项目的主体代码。
我主要把 AI 用在别人的项目和历史遗留代码,这可以避免读懂他人代码的巨大时间成本。
就拿历史遗留代码为例,(1)很多时候没有足够的文档,也没有作者的说明,(2)技术栈和工具库都过时了,读懂代码还要翻找以前的标准,(3)最极端的情况下,只有构建产物,没有源代码,根本无法着手。
AI 简直就是这类代码的救星,再古老的代码,它都能读懂和修改,甚至还能对构建产物进行逆向工程。
下面就是我怎么用 AI 处理历史遗留代码,平时我基本就是这样来 AI 编程。
三、
我的 AI 编程工具是 Claude Code。因为命令行对我更方便,也容易跟其他工具集成。
我使用的 AI 模型,大部分时间是国产的 MiniMax M2。我测过它的功能,相当不错,能够满足需要,它的排名也很靠前。
![]()
另外,它有包月价(29元人民币),属于最便宜的编程模型之一,可以放心大量使用,反复试错。要是改用大家都趋之若鹜的 Claude 系列模型,20美元的 Pro 套餐不够用,200美元的 Max 套餐又太贵。
MiniMax 接入 Claude Code 的方法,参考我的这篇教程。
四、
就在我写这篇文章的时候,MiniMax 本周进行了一次大升级,M2 模型升级到了 M2.1。
![]()
因为跟自己相关,我特别关注这次升级。
根据官方的发布声明,这次升级特别加强了"多语言编程能力",对于常用编程语言(Rust、Java、Golang、C++、Kotlin、Objective-C、TypeScript、JavaScript 等)有专门强化。
它的 WebDev 与 AppDev 开发能力因此有大幅提升,可以用来开发复杂的 Web 应用和 Android/iOS 的原生 App。
"在软件工程相关场景的核心榜单上,MiniMax M2.1 相比于 M2 有了显著的提升,尤其是在多语言场景上,超过 Claude Sonnet 4.5 和 Gemini 3 Pro,并接近 Claude Opus 4.5。"
根据上面这段介绍,它的编程能力,超出或接近了国外旗舰模型。
这个模型已经上线了,现在就能用。那么,这篇文章正好测一下,官方的介绍是否准确,它的 Web 开发能力到底有没有变强。
至于价格,跟原来一样。但是,官方表示"响应速度显著提升,Token 消耗明显下降",也算变相降价了。
M2.1 接入 Claude Code,我的参数如下。
![]()
五、
我这次选择的历史遗留项目是 wechat-format,一个 Web 应用,将 Markdown 文本转为微信公众号的样式。
![]()
上图左侧的文本框输入 Markdown 文本,右侧立刻显示自动渲染的结果,可以直接复制到微信公众号的编辑器。
它非常好用,大家可以去试试看。我的公众号现在就用它做排版,效果不错(下图)。
![]()
问题是,原作者六年前就放弃了,这个项目不再更新了。我看过源码,它用的是老版本的 Vue.js 和 CodeMirror 编辑器,没有任何文档和说明,还经过了编译工具的处理,注释都删掉了。
如果不熟悉它的技术栈,想要修改这些代码是很困难的,可能要投入大量时间。
那么废话少说,直接让 AI 上场,把这些代码交给 MiniMax M2.1 模型。
六、
接手老项目的第一步,是对项目进行一个总体的了解。
我首先会让 AI 生成项目概述。大家可以跟着一起做,跟我的结果相对照。
# 克隆代码库 $ git clone git@github.com:ruanyf/wechat-format.git # 进入项目目录 $ cd wechat-format # 启动 Claude Code $ claude-minimax
上面的claude-minimax是我的自定义命令,用来在 Claude Code 里面调用 MiniMax 模型(参见教程)。
输入"生成这个仓库的概述"。
![]()
AI 很快就给出了详细说明,包括项目的总体介绍、核心功能、技术栈和文件结构(下图)。
![]()
有了总体了解以后,我会让 AI 解释主要脚本文件的代码。
【提示词】解释 index.html 文件的代码
![]()
它会给出代码结构和页面布局(上图),然后是 JS 脚本加载顺序和 Vue 应用逻辑,甚至包括了流程图(下图),这可是我没想到的。
![]()
![]()
做完这一步,代码库的大致情况应该就相当了解了,而 AI 花费的时间不到一分钟。
七、
既然这个模型号称有"多语言编程能力",我就让它把项目语言从 JavaScript 改成 TypeScript。
对于很多老项目来说,这也是常见需求,难度不低。
![]()
它先制定了迁移计划,然后生成了 tsconfig.json 和 types.d.ts,并逐个将 JS 文件转为对应的 TS 文件(下图)。
![]()
修改完成后,它试着运行这个应用,发现有报错(下图),于是又逐个解决错误。
![]()
最终,迁移完成,它给出了任务总结(下图)。
![]()
我在浏览器运行这个应用,遇到了两个报错:CodeMirror 和 FuriganaMD 未定义。
我把报错信息提交给模型,它很快修改了代码,这次就顺利在浏览器跑起来了。
至此,这个多年前的 JavaScript 应用就成功改成了 TypeScript 应用,并且所有内部对象都有了完整的类型定义。
你还可以接着添加单元测试,这里就省略了。
八、
简单的测试就到此为止,我目前的 AI 编程大概就到这个程度,用 AI 来解释和修改代码。我也建议大家,以后遇到历史遗留代码,一律先交给 AI。
虽然这个测试比较简单,不足以考验 MiniMax M2.1 的能力上限,但如果人工来做上面这些事情,可能一个工作日还搞不定,但是它只需要十几分钟。
总体上,我对它的表现比较满意。大家都看到了,我的提示词很简单,就是一句话,但是它正确理解了意图,如果一次没有成功,最多再修改一两次就正确了。
而且,就像发布说明说的一样,它运行速度很快,思考过程和生成过程最多也就两三分钟,不像有的模型要等很久。
另外,不管什么操作,它都会给出详细的讲解和代码注释。
总之,就我测试的情况来看,这个模型的 Web 开发能力确实很不错,可以用于实际工作。
最后,说一点题外话。著名开发者 Simon Willison 最近说,评测大模型越来越困难,"我识别不出两个模型之间的实质性差异",因为主流的新模型都已经足够强大,足以解决常见任务,只有不断升级评测的难度,才能测出它们的强弱。
这意味着,对于普通程序员的常见编程任务,不同模型不会构成重大差异,没必要迷信国外的旗舰模型,国产模型就很好用。
(完)
文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
- 发表日期: 2025年12月23日
美团 LongCat-Video-Avatar 正式发布,实现开源 SOTA 级拟真表现
你以为 Props 只是传参? 不,它是 React 组件设计的“灵魂系统”
90% 的 React 初学者,都低估了 Props。
他们以为它只是“从父组件往子组件传点数据”。
但真正写过复杂组件、设计过通用组件的人都知道一句话:
Props 决定了一个组件“好不好用”,而不是“能不能用”。
这篇文章,我们不讲 API 清单、不背概念,
而是围绕 Props 系统的 5 个核心能力,一次性讲透 React 组件化的底层逻辑:
- Props 传递
- Props 解构
- 默认值(defaultProps / 默认参数)
- 类型校验(PropTypes)
- children 插槽机制(React 的核武器)
👉 看完你会明白:
React 真正厉害的不是 JSX,而是 Props 设计。
一、Props 的本质:组件的“对外接口”
先抛一个结论:
React 组件 ≈ 一个函数 + 一套 Props 接口
来看一个最简单的组件 👇
function Greeting(props) {
return <h1>Hello, {props.name}</h1>
}
使用时:
<Greeting name="白兰地" />
很多人到这里就停了,但问题是:
❓
name到底是什么?
答案是:
name 不是变量,是组件对外暴露的能力。
Props 本质上是:
- 父组件 👉 子组件的输入
- 组件作者 👉 使用者的约定
二、Props 解构:不是语法糖,而是“设计声明”
对比两种写法 👇
❌ 不推荐
function Greeting(props) {
return <h1>Hello, {props.name}</h1>
}
✅ 推荐
function Greeting({ name }) {
return <h1>Hello, {name}</h1>
}
为什么?
解构不是为了少写字,而是为了表达意图。
当你看到函数签名:
function Greeting({ name, message, showIcon }) {}
你立刻就知道:
- 这个组件“需要什么”
- 组件的“输入边界”在哪里
👉 好的组件,从函数签名就能读懂。
三、Props 默认值:组件“健壮性”的第一步
看这个组件 👇
function Greeting({ name, message }) {
return (
<div>
<h1>Hello, {name}</h1>
<p>{message}</p>
</div>
)
}
如果使用者这么写:
<Greeting name="空瓶" />
会发生什么?
message === undefined
这时候就轮到 默认值 出场了。
方式一:defaultProps(经典)
Greeting.defaultProps = {
message: 'Welcome!'
}
方式二:解构默认值(更推荐)
function Greeting({ name, message = 'Welcome!' }) {}
💡默认值不是兜底,而是组件设计的一部分。
它代表的是:
- “在你不配置的情况下”
- “组件应该表现成什么样”
四、Props 类型校验:组件的“自说明文档”
来看一段很多人忽略、但非常值钱的代码 👇
import PropTypes from 'prop-types'
Greeting.propTypes = {
name: PropTypes.string.isRequired,
message: PropTypes.string,
showIcon: PropTypes.bool,
}
很多人会说:
“这不是可有可无吗?”
但在真实项目里,它解决的是:
- ❌ 参数传错没人发现
- ❌ 新人不知道组件怎么用
- ❌ 组件一多,全靠猜
🔍 PropTypes 的真正价值
不是防 bug,而是“降低理解成本”。
当你看到 propTypes,就等于看到一份说明书:
- 哪些 props 必须传?
- 哪些是可选?
- 类型是什么?
👉 一个没有 propTypes 的通用组件,本质上是“黑盒”。
五、children:React Props 系统的“王炸”
如果只能选一个 Props 机制,我会毫不犹豫选:
🧨 children
来看一个 Card 组件 👇
const Card = ({ children, className = '' }) => {
return (
<div className={`card ${className}`}>
{children}
</div>
)
}
使用时:
<Card className="user-card">
<h2>张三</h2>
<p>高级前端工程师</p>
<button>查看详情</button>
</Card>
这里发生了一件非常重要的事情:
组件不再关心“内容是什么”。
🧠 children 的设计哲学
组件负责“骨架”,使用者负责“填充”。
- Card 只负责:边框、阴影、间距
- children 决定:展示什么内容
这让组件具备了两个特性:
- ✅ 高度复用
- ✅ 永不过期
六、children + Props = 通用组件的终极形态
再看一个更高级的例子:Modal 👇
<Modal HeaderComponent={MyHeader} FooterComponent={MyFooter}>
<p>这是一个弹窗</p>
<p>你可以在这里显示任何 JSX</p>
</Modal>
Modal 的实现:
function Modal({ HeaderComponent, FooterComponent, children }) {
return (
<div>
<HeaderComponent />
{children}
<FooterComponent />
</div>
)
}
这背后是一个非常高级的思想:
Props 不只是数据,也可以是组件。
七、请记住这 5 条 Props 设计铁律
🔥 如果你只能记住一段话,请记住这里
- Props 是组件的“对外接口”,不是随便传的变量
- 解构 Props,是在声明组件的能力边界
- 默认值,决定组件的“基础体验”
- 类型校验,让组件自带说明书
- children,让组件从“可用”变成“好用”
八、写在最后
当你真正理解 Props 之后,你会发现:
- React 不只是 UI 库
- 它在教你如何设计 API
- 如何让别人“用得爽”
Props 写得好不好,决定了一个人 React 水平的上限。
每日一题-两个最好的不重叠活动🟡
给你一个下标从 0 开始的二维整数数组 events ,其中 events[i] = [startTimei, endTimei, valuei] 。第 i 个活动开始于 startTimei ,结束于 endTimei ,如果你参加这个活动,那么你可以得到价值 valuei 。你 最多 可以参加 两个时间不重叠 活动,使得它们的价值之和 最大 。
请你返回价值之和的 最大值 。
注意,活动的开始时间和结束时间是 包括 在活动时间内的,也就是说,你不能参加两个活动且它们之一的开始时间等于另一个活动的结束时间。更具体的,如果你参加一个活动,且结束时间为 t ,那么下一个活动必须在 t + 1 或之后的时间开始。
示例 1:
![]()
输入:events = [[1,3,2],[4,5,2],[2,4,3]] 输出:4 解释:选择绿色的活动 0 和 1 ,价值之和为 2 + 2 = 4 。
示例 2:
![]()
输入:events = [[1,3,2],[4,5,2],[1,5,5]] 输出:5 解释:选择活动 2 ,价值和为 5 。
示例 3:
![]()
输入:events = [[1,5,3],[1,5,1],[6,6,5]] 输出:8 解释:选择活动 0 和 2 ,价值之和为 3 + 5 = 8 。
提示:
2 <= events.length <= 105events[i].length == 31 <= startTimei <= endTimei <= 1091 <= valuei <= 106