HarmonyOS ArkTS 的新手练手样例:用 List 和 ForEach 做一个待办列表
开头
很多应用都绕不开列表:消息列表、商品列表、设置项、文章列表、任务列表。ArkTS 里可以用 List 和 ListItem 展示列表,用 ForEach 根据数组生成重复界面。
这一篇我们做一个待办列表:输入任务,点击添加,下面列表自动多一条。
本篇目标
- 会用数组保存列表数据。
- 会用
ForEach渲染多条内容。 - 会用
List和ListItem组织列表。 - 会删除列表中的某一项。

示例代码
interface TodoItem {
id: number;
title: string;
done: boolean;
}
@Entry
@Component
struct TodoPage {
@State inputText: string = '';
@State todos: TodoItem[] = [
{ id: 1, title: '学习 Text 和 Button', done: true },
{ id: 2, title: '练习 TextInput', done: false }
];
private nextId: number = 3;
private addTodo() {
const title = this.inputText.trim();
if (title.length === 0) {
return;
}
this.todos = [
...this.todos,
{ id: this.nextId, title, done: false }
];
this.nextId += 1;
this.inputText = '';
}
private removeTodo(id: number) {
this.todos = this.todos.filter((item: TodoItem) => item.id !== id);
}
build() {
Column({ space: 16 }) {
Text('我的待办')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.width('100%')
Row({ space: 8 }) {
TextInput({ placeholder: '输入一个新任务', text: this.inputText })
.layoutWeight(1)
.height(44)
.onChange((value: string) => {
this.inputText = value;
})
Button('添加')
.height(44)
.onClick(() => {
this.addTodo();
})
}
List({ space: 10 }) {
ForEach(this.todos, (item: TodoItem) => {
ListItem() {
Row({ space: 12 }) {
Text(item.done ? '已完成' : '未完成')
.fontSize(12)
.fontColor(item.done ? '#008A45' : '#666666')
Text(item.title)
.fontSize(16)
.layoutWeight(1)
.decoration({
type: item.done ? TextDecorationType.LineThrough : TextDecorationType.None
})
Button('删除')
.height(32)
.onClick(() => {
this.removeTodo(item.id);
})
}
.width('100%')
.padding(12)
.borderRadius(8)
.backgroundColor('#F5F5F5')
}
}, (item: TodoItem) => item.id.toString())
}
.layoutWeight(1)
.width('100%')
}
.width('100%')
.height('100%')
.padding(20)
}
}
小白看懂代码
todos 是待办数组。列表页面一般都离不开数组。
ForEach(this.todos, ...) 表示根据 todos 数组生成多条列表项。
ListItem() 是列表中的一行。每一行里又放了一个 Row,左边是状态,中间是任务标题,右边是删除按钮。
添加任务时,没有直接 push:
this.todos = [
...this.todos,
{ id: this.nextId, title, done: false }
];
这样写更符合声明式 UI 的思路:生成一个新的数组,再赋值给状态。
删除任务时用 filter:
this.todos = this.todos.filter((item: TodoItem) => item.id !== id);
意思是保留所有 id 不等于目标值的任务。
为什么 ForEach 需要 key
代码最后有一段:
(item: TodoItem) => item.id.toString()
这就是列表项的唯一标识。列表新增、删除、刷新时,框架需要知道“哪一条是哪一条”。实际项目中不要用重复值当 key。
可以怎么改
可以给每条任务加一个完成按钮:
Button(item.done ? '恢复' : '完成')
.height(32)
.onClick(() => {
this.todos = this.todos.map((todo: TodoItem) => {
if (todo.id === item.id) {
return { id: todo.id, title: todo.title, done: !todo.done };
}
return todo;
});
})
也可以把待办列表改成文章列表、课程列表、商品列表。只要是“数组数据变成多行界面”,都可以先从这个例子改。
本篇小结
列表的核心不是 List 本身,而是“数据数组 + ForEach 渲染 + 唯一 key”。新手先把新增、删除跑通,再去学复杂的列表刷新、分页、懒加载,会轻松很多。
附录:项目设置与构建问题记录
一、项目设置
本篇配套一个独立 ArkTS 示例 App,用于运行页面和截图:

建议用 DevEco Studio 打开项目后运行 entry 模块。项目定位是截图练习 Demo,不依赖后端服务,也不需要额外权限。
建议新建或检查工程时保持以下设置:
- Project type:Application。
- Template:Empty Ability。
- Language:ArkTS。
- Model:Stage。
- Device:Phone,可按需要兼容 Tablet、2in1。
- Runtime OS:HarmonyOS。


二、SDK 版本
本文主题面向 HarmonyOS ArkTS API 24+。本次示例工程根目录 build-profile.json5 使用如下配置:
{
"compatibleSdkVersion": "6.1.1(24)",
"targetSdkVersion": "6.1.1(24)",
"runtimeOS": "HarmonyOS"
}
如果本机 DevEco Studio SDK Manager 中安装的版本不同,请按本机实际 API 24+ SDK 调整 compatibleSdkVersion 和 targetSdkVersion。
三、项目目录说明

核心目录如下:
HarmonyOS_ArkTS_API24_ControlsScreenshotApp/
├── AppScope/
│ ├── app.json5
│ └── resources/
├── entry/
│ ├── src/main/ets/entryability/EntryAbility.ets
│ ├── src/main/ets/pages/
│ ├── src/main/resources/base/profile/main_pages.json
│ ├── build-profile.json5
│ └── oh-package.json5
├── build-profile.json5
├── hvigorfile.ts
└── oh-package.json5
页面文件都在:
entry/src/main/ets/pages/
路由注册文件在:
entry/src/main/resources/base/profile/main_pages.json
五、创建项目过程
- 打开 DevEco Studio。
- 点击 Create Project。
- 选择 Application。
- 模板选择 Empty Ability。
- 开发语言选择 ArkTS。
- 模型选择 Stage。
- 设置项目名称,例如
ArkTSControlsDemo。 - 选择保存路径,建议路径只包含英文、数字、下划线或连字符。
- 选择 API 24+ 对应 SDK。
- 点击 Finish,等待工程创建完成。
- 打开
entry/src/main/ets/pages/Index.ets。 - 运行默认工程,确认模拟器或真机能打开。
- 再逐个添加本文中的页面代码并截图。
六、本次编译安装遇到的问题与解决办法
1. 中文路径导致 Hvigor 拒绝构建
问题现象:
Invalid project path. Current path does not match: D:\私人资料\CSDN\HarmonyOS_ArkTS_API24_ControlsScreenshotApp
原因:Hvigor 对工程路径有限制,路径只能包含英文字母、数字、连字符、下划线、英文句点、英文括号、空格或 @。
处理办法:把项目复制到 ASCII 路径后构建:
D:\\HarmonyOS_ArkTS_API24_ControlsScreenshotApp
2. DEVECO_SDK_HOME 环境变量无效
问题现象:
Invalid value of 'DEVECO_SDK_HOME' in the system environment path.
处理办法:在当前命令会话中临时指定 DevEco SDK 根目录:
$env:DEVECO_SDK_HOME='D:\Program Files\Huawei\DevEco Studio Beta\sdk'
3. hvigor-config.json5 缺少 dependencies
问题现象:
Schema validate failed ... missingProperty: 'dependencies'
处理办法:补齐 hvigor/hvigor-config.json5:
{
"modelVersion": "5.0.0",
"dependencies": {
}
}
4. 打包阶段找不到 Java
问题现象:
spawn java ENOENT
处理办法:使用 DevEco Studio 自带 JBR,并停止旧的 Hvigor daemon 后重新构建:
$env:JAVA_HOME='D:\Program Files\Huawei\DevEco Studio Beta\jbr'
$env:Path="D:\Program Files\Huawei\DevEco Studio Beta\jbr\bin;$env:Path"
hvigorw --stop-daemon
5. 构建成功但有弃用警告
构建时出现过 router.pushUrl、router.back、AlertDialog.show 的弃用警告,但不影响本次截图 Demo 编译和安装。正式项目建议后续按当前 API 推荐方式替换。
七、本次安装启动记录
构建命令:
hvigorw --mode module -p module=entry@default -p product=default assembleHap
安装命令:
hdc install entry-default-unsigned.hap
启动命令:
hdc shell aa start -a EntryAbility -b com.csdn.arkts.controls.screenshot
验证结果:
- HAP 构建成功。
- 模拟器目标:
127.0.0.1:5555。 - 安装结果:
install bundle successfully。 - 启动结果:
start ability successfully。
更多推荐

所有评论(0)