🧱 写在前面
很多 React 开发者初学 HarmonyOS 时,第一反应是:
“我的 div 去哪了?怎么写 <p>?<input> 还能用吗?”
答案是:HTML 元素在鸿蒙中不存在。取而代之的是一套声明式原生 UI 组件:Column、Text、TextInput、Button……
但别担心——这些组件的设计哲学与 React 高度一致。 本期我们将系统对比 React 常用元素 vs HarmonyOS 组件,助你快速建立“组件映射认知”,告别迷茫。
🗺️ 1. 核心布局容器:Column / Row / Stack
在 Web 开发中,<div> 配合 CSS Flex 实现布局。 在 ArkTS 中,布局由三大容器直接定义:
| 垂直排列 | <div style={{ display: 'flex', flexDirection: 'column' }}> | Column() | 子元素垂直排布 |
| 水平排列 | <div style={{ display: 'flex', flexDirection: 'row' }}> | Row() | 子元素横向排布 |
| 层叠覆盖 | 父容器 position: relative + 子元素 absolute | Stack() | 子元素按添加顺序堆叠 |
示例:用户信息卡片
@Preview
@Component
struct ProfileCard {
build() {
Column() {
Image($r('app.media.startIcon'))
.width(80)
.height(80)
.borderRadius(40)
Text('张三')
.fontSize(18)
.fontWeight(FontWeight.Bold)
Button('关注')
.margin({ top: 10 })
}
.width(200)
.padding(20)
.backgroundColor('#f9f9f9')
.alignItems(HorizontalAlign.Center) // ← 水平居中子元素
}
}

💡 Column 和 Row 是 弹性布局容器,.alignItems() 相当于 CSS 的 align-items。
🔤 2. 文本与输入控件
| 静态文本 | <p>Hello</p> | Text('Hello') | 支持富文本(需 Span) |
| 单行输入 | <input type="text" /> | TextInput({ text: value }) | 必须绑定状态 |
| 多行输入 | <textarea /> | TextArea({ text: value }) | 自动高度扩展 |
TextInput 正确用法
@State message: string = '';
build() {
Column() {
TextInput({
text: this.message,
placeholder: '请输入消息'
})
.onChange((value) => {
this.message = value; // 手动同步状态
})
Text(`当前内容: ${this.message}`)
.margin({
top: 16
})
}
.padding(20)
}

⚠️ TextInput 不会自动双向绑定!必须通过 onChange 更新 @State 或使用 @Link。
🖱️ 3. 交互控件:Button、Image、Toggle
| 按钮 | <button> | Button('确定').onClick(…) | 支持加载状态、图标 |
| 图片 | <img src="…" /> | Image($r('app.media.logo')) | 自动缓存、缩放、圆角 |
| 开关 | react-switch 等第三方 | Toggle({ isOn: true }) | 原生支持,无需依赖 |
| 滑块 | <input type="range" /> | Slider({ value: 50 }) | 支持颜色、步长定制 |
图片资源路径说明
- 本地图片:Image($r('app.media.icon_name')) // 文件路径:resources/base/media/icon_name.png
- 网络图片:Image('https://example.com/logo.png')
✅ 鸿蒙 Image 组件内置性能优化,比 Web <img> 更高效。
📋 4. 列表与滚动容器:List + ListItem
虽然渲染逻辑由 ForEach 处理(下期详解),但滚动容器由 List 提供:
| 可滚动列表 | <div style={{ overflowY: 'auto' }}> + map | List() { ListItem() { … } } |
| 性能优化 | 需 react-window / virtuoso | List 内置视图复用 & 懒加载 |
基础 List 用法
@State items: Array<{ id: number, title: string }> = [
{ id: 1, title: 'Item 1' },
{ id: 2, title: 'Item 2' }
];
build() {
List() {
ForEach(this.items, item => {
ListItem() {
Text(item.title)
.padding(15)
.width('100%')
}
}, item => item.id.toString())
}
.height(300) // ← 必须设置高度才能滚动!
}
🔜 后续我们将深入 ForEach 的 key 机制与高性能列表实践。
🧩 5. 条件渲染与循环:直接用 TypeScript 语法
在 React 中,JSX 限制了逻辑表达:
{isVisible && <Comp />}
{items.map(item => <Item key={item.id} />)}
在 ArkTS 中,直接使用标准 TS 语法,更自由:
build() {
Column() {
if (this.isVisible) {
MyComponent()
}
for (let i = 0; i < 3; i++) {
Text(`Item ${i}`)
.margin({ bottom: 10 })
}
}
}
✅ 优势:无需处理 null、无需包装数组,逻辑更直观。
⚠️ 6. 新手常见错误(避坑指南)
❌ 错误 1:List 未设置高度
List() { /* … */ } // ❌ 无法滚动!
✅ 正确:
List() { /* … */ }.height('100%') // 或固定值如 .height(400)
❌ 错误 2:布局容器误用
// 想水平排两个按钮?
Column() {
Button('A')
Button('B')
} // ❌ 结果是垂直排列!
✅ 正确:
Row() {
Button('A')
Button('B')
}
.margin({ horizontal: 10 })
❌ 错误 3:样式写成对象(React 风格)
Text('Hello').style({ fontSize: 20 }) // ❌ ArkTS 不支持!
✅ 正确:链式方法调用
Text('Hello')
.fontSize(20)
.fontColor('#333333')
.margin({ top: 10, left: 20 })
✅ 小结
- ✅ 布局:Column / Row / Stack → 替代 flex / absolute 定位
- ✅ 内容:Text / Image → 替代 p / img
- ✅ 交互:Button / TextInput / Toggle → 原生控件,功能更强
- ✅ 逻辑:直接用 if / for,无 JSX 限制
- ✅ 样式:链式调用 .method(),非 CSS 对象
你不是失去了 HTML,而是获得了更强大、更高效的原生 UI 能力。
🔜 下期预告
《从 useEffect 到 onAppear/onPageShow》 我们将深入:
- 组件挂载/卸载时如何执行逻辑?
- 页面级生命周期如何监听?
- 如何正确清理定时器、取消订阅?
关注我,持续解锁 React → 鸿蒙实战技能!
📚 参考资料
- HarmonyOS 官方文档 – 组件布局
- HarmonyOS 官方文档 – 列表与网格
- HarmonyOS 官方文档 – 使用文本
系列名称:《React 开发者的鸿蒙入门指南》
✅ 欢迎点赞、收藏、评论交流!你的支持是我持续输出的动力! ✅ 点击主页关注,获取更多前端 × 鸿蒙实战内容!
💬 互动提问:你在使用 Column 或 TextInput 时遇到过哪些奇怪问题?留言告诉我,点赞最高的问题,下期优先解答!
网硕互联帮助中心



评论前必须登录!
注册