HarmonyOS ArkTS 的新手练手样例:用 List 和 ForEach 做一个待办列表
开头
很多应用都绕不开列表:消息列表、商品列表、设置项、文章列表、任务列表。ArkTS 里可以用List和ListItem展示列表,用ForEach根据数组生成重复界面。
这一篇我们做一个待办列表:输入任务,点击添加,下面列表自动多一条。
本篇目标
- 会用数组保存列表数据。
- 会用
ForEach渲染多条内容。 - 会用
List和ListItem组织列表。 - 会删除列表中的某一项。
示例代码
interfaceTodoItem{id:number;title:string;done:boolean;}@Entry@Componentstruct TodoPage{@StateinputText:string='';@Statetodos:TodoItem[]=[{id:1,title:'学习 Text 和 Button',done:true},{id:2,title:'练习 TextInput',done:false}];privatenextId:number=3;privateaddTodo(){consttitle=this.inputText.trim();if(title.length===0){return;}this.todos=[...this.todos,{id:this.nextId,title,done:false}];this.nextId+=1;this.inputText='';}privateremoveTodo(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};}returntodo;});})也可以把待办列表改成文章列表、课程列表、商品列表。只要是“数组数据变成多行界面”,都可以先从这个例子改。
本篇小结
列表的核心不是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_ControlsScreenshotApp2.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-daemon5. 构建成功但有弃用警告
构建时出现过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 aastart-a EntryAbility-b com.csdn.arkts.controls.screenshot验证结果:
- HAP 构建成功。
- 模拟器目标:
127.0.0.1:5555。 - 安装结果:
install bundle successfully。 - 启动结果:
start ability successfully。