HarmonyOS APP<玩转React>开源教程十九:CodeBlock 代码块组件
第19次:CodeBlock 代码块组件
从这一篇开始,我们进入“课程内容展示体验优化”的部分。当前项目里真正承担代码展示任务的组件是
entry/src/main/ets/components/CodeBlock.ets,它会被LessonDetail.ets调用,用来展示标题、语言标签、代码正文、说明文字和复制能力。
为什么教程类应用一定要做代码块组件
如果你在课时详情页里直接用一个普通 Text 显示代码,马上就会遇到这些问题:
- 代码和正文混在一起,视觉层次很差。
- 用户不知道这段代码是什么语言。
- 没办法一键复制去试验。
- 代码解释没有固定位置,内容会很乱。
所以一个成熟一点的学习类应用,都会把代码展示抽成单独组件。这个项目的 CodeBlock 虽然不复杂,但结构很完整,非常适合入门项目学习。
一、CodeBlock 组件到底接收了哪些参数
当前组件接收四个核心属性:
codelanguagetitleexplanation
这四个参数看起来简单,但已经足够覆盖大多数教学场景了。
code
真正要展示的代码内容,是组件的核心主体。
language
用于生成右上角语言标签,比如 TSX、JSX、TS。哪怕当前版本没有做真正的语法高亮,用户也能第一眼知道这段代码是什么类型。
title
告诉用户这段代码在讲什么,例如“函数组件示例”“状态更新写法”“Effect 清理函数示例”。这能显著提升可读性。
explanation
这是很多教程最容易忽略、却最有价值的一部分。代码展示出来以后,必须有人话解释,不然用户只能“看见”,不能“理解”。
二、这个组件的结构为什么很合理
CodeBlock 不是简单地上下堆几个控件,它分成了三个稳定层次:
- 顶部标题栏
- 中间代码区域
- 底部解释说明
其中标题栏里还继续拆分成:
- 左侧标题
- 右侧语言标签
- 复制按钮
这样的结构非常符合用户阅读代码时的习惯:
- 先知道这段代码叫什么
- 再看正文
- 最后看解释
这比把说明塞在代码上面、或者把复制按钮放到页面角落,都更自然。
三、为什么代码区要放在 Scroll() 里
教学类应用的代码长度是不稳定的。有时候只有三五行,有时候可能几十行。如果不用 Scroll(),代码会把整页高度撑爆,尤其在手机上更明显。
当前实现把代码区包在 Scroll() 中,并限制最大高度:
.constraintSize({ maxHeight: 300 }).scrollBar(BarState.Auto)
这两个设置配合起来就很实用:
- 短代码不会浪费空间。
- 长代码也不会撑破布局。
- 用户知道这里是可以滚动的。
对于鸿蒙手机端来说,这种“限制高度 + 局部滚动”的代码展示方式几乎是标配。
四、复制能力是怎么实现的
组件用的是:
@kit.BasicServicesKit中的pasteboard@kit.ArkUI中的promptAction.showToast
整体流程很清晰:
这套实现的教学意义很强,因为它不是纯 UI,而是把鸿蒙的系统服务能力真正用起来了。对于初学者来说,这也是一个很好的例子:组件并不只是负责显示,它也可以承担轻量交互和系统能力调用。
五、为什么解释说明单独放在底部
很多教程喜欢把代码解释写在代码上方,但当前项目把解释说明放到代码下面,这种顺序其实更适合学习:
- 先整体看代码长什么样
- 再通过说明理解“这段代码要表达什么”
同时,解释区使用了和代码区不同的底色,让用户能明确区分:
- 这里不是代码正文
- 这里是作者的解释
这在教学产品中非常重要。用户在读教程时最怕“哪部分是代码,哪部分是说明”混在一起。
六、它和 LessonDetail 的关系一定要看清楚
CodeBlock 本身只是一个渲染组件,并不关心课时、模块、进度这些业务。真正把它放进教学流程的是 LessonDetail.ets。
也就是说,两者分工很明确:
LessonDetail决定展示哪些代码示例CodeBlock决定这些示例怎么显示
这种拆分特别值得你学习,因为它体现了组件化的核心思想:
- 页面负责业务组织
- 组件负责局部展示
如果以后你要给题库页、源码详情页、项目说明页也加代码展示,只要继续复用 CodeBlock 就行,不需要重复造轮子。
七、自己动手验证时怎么做
- 打开任意课时详情页,找到代码示例区域。
- 观察标题、语言标签、代码正文、解释说明是否都能正确显示。
- 点击复制按钮,确认系统提示是否出现。
- 选一段较长代码,测试局部滚动是否正常。
- 切换深色模式,观察标题栏、正文区、说明区颜色是否仍然清晰。
只要这五步你自己跑一遍,就会对这个组件的职责非常清楚。
八、本篇常见坑
1. 把代码块写死在页面里
这样后面每个页面都要重复写样式,维护成本会快速上升。
2. 代码区不做高度限制
一旦代码稍长,手机页面就会非常难看。
3. 只展示代码,不提供说明
教程不是代码仓库,代码一定要配解释。
4. 忽略复制功能
用户看到可运行示例后,往往第一反应就是复制去试。没有复制按钮会很影响体验。
本篇小结
CodeBlock 组件看似小,但它把“教学代码展示”这件事做得非常完整:
- 有标题
- 有语言标签
- 有可滚动代码区
- 有解释说明
- 还能一键复制
你以后做任何知识型、教程型、文档型鸿蒙应用,都几乎离不开这样一个基础组件。
跟着真实源码继续往下看
下面这段就是项目里 CodeBlock.ets 的真实核心实现:
if (this.title) {
Row() {
Text(this.title)
Blank()
Text(this.language.toUpperCase())
Text('📋')
.onClick(() => this.copyCode())
}
}
Scroll() {
Text(this.code)
.fontSize(13)
.fontFamily('monospace')
}
.constraintSize({ maxHeight: 300 })
复制逻辑的真实代码如下:
private copyCode(): void {
try {
const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, this.code);
const systemPasteboard = pasteboard.getSystemPasteboard();
systemPasteboard.setData(pasteboardData);
promptAction.showToast({ message: '代码已复制' });
} catch (error) {
console.error('[CodeBlock] Failed to copy:', error);
promptAction.showToast({ message: '复制失败' });
}
}
按这个顺序动手
- 打开
entry/src/main/ets/components/CodeBlock.ets。 - 先看标题栏如何把标题、语言和复制按钮放到一行。
- 再看
copyCode(),理解鸿蒙剪贴板能力怎么接入组件。
课后练习
- 思考如果你要给
CodeBlock增加“折叠/展开”功能,最适合新增什么状态字段。 - 观察当前组件并没有真正做关键字级别语法高亮,想一想如果后续要加,应该在组件层做还是在数据预处理层做。
- 总结
CodeBlock为什么适合作为通用组件,而不该耦合 Lesson 或 Module 业务字段。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)