鸿蒙 ArkTS 任务管理应用实战:声明式 List 组件深度解析

项目概述
传统移动端常依赖手动刷新与繁琐的状态管理来驱动 UI 更新;而在 HarmonyOS 的 ArkTS 框架中,ArkUI 以“声明式 UI + 响应式数据绑定”重塑开发范式,显著简化界面构建与状态同步。本文以「任务管理」为例,完整实现增删改查、状态切换与筛选过滤等能力,展示从页面到逻辑的端到端实践。
| 特性 | 传统开发 | ArkTS(ArkUI) |
|---|---|---|
| UI 构建 | XML/HTML 模板 | 声明式 UI(直接描述界面结构) |
| 状态管理 | 手动刷新视图 | @State 自动刷新 UI |
| 列表渲染 | RecyclerView/ListView + Adapter | List + ForEach 声明式渲染 |
| 数据更新 | notifyDataSetChanged() 手动通知 |
数组操作自动触发 UI 更新 |
| 布局方式 | 多层嵌套布局 | Column/Row/List 容器简洁组织 |
| 事件处理 | 回调监听器 | 直接绑定函数,链式调用 |
| 性能优化 | 手动 ViewHolder 复用 | 自动虚拟化与回收机制 |
| 代码结构 | 多文件耦合 | 单 ETS 文件即可实现复杂功能 |
实现效果

架构设计与实现过程
数据模型定义
通过 interface TaskItem 定义任务数据结构:
interface TaskItem {
id: number
title: string
completed: boolean
createTime: string
}
id:唯一标识任务title:任务标题completed:任务完成状态createTime:任务创建时间
通过 @State 响应式管理核心状态:
tasks:任务数组newTaskTitle:新任务输入内容filterType:筛选类型(全部/待办/已完成)
UI 构建逻辑
采用声明式 UI,通过 Column 组件组织布局:
Column({ space: 20 }) {
this.buildHeader()
this.buildAddTaskSection()
this.buildFilterTabs()
this.buildTaskList()
}
各区域模块化构建:
buildHeader():标题与统计信息buildAddTaskSection():输入与添加任务buildFilterTabs():任务筛选标签栏buildTaskList():任务列表展示区
任务操作逻辑
添加任务:通过时间戳生成唯一 ID,将新任务添加至 tasks 数组。
addTask() {
const newTask: TaskItem = {
id: Date.now(),
title: this.newTaskTitle.trim(),
completed: false,
createTime: new Date().toISOString().split('T')[0]
}
this.tasks.push(newTask)
this.newTaskTitle = ''
}

状态切换:点击任务后切换 completed 状态,实现待办/已完成切换。
toggleTaskStatus(taskId: number) {
const taskIndex = this.tasks.findIndex(task => task.id === taskId)
if (taskIndex !== -1) {
this.tasks[taskIndex].completed = !this.tasks[taskIndex].completed
}
}

删除任务:通过 filter 操作删除指定任务,数据更新后 UI 自动同步。
deleteTask(taskId: number) {
this.tasks = this.tasks.filter(task => task.id !== taskId)
}
筛选与过滤逻辑
通过 getFilteredTasks() 方法按 filterType 返回不同任务列表,结合条件渲染动态展示对应任务集合。
● all:返回所有任务
● pending:仅返回未完成任务
● completed:仅返回已完成任务
getFilteredTasks(): TaskItem[] {
switch (this.filterType) {
case 'pending':
return this.tasks.filter(task => !task.completed)
case 'completed':
return this.tasks.filter(task => task.completed)
default:
return this.tasks
}
}
动态样式与交互反馈
样式切换
高亮当前筛选状态,区分已完成与未完成任务。
.fontColor(this.filterType === type ? '#FFFFFF' : '#666666')
.backgroundColor(task.completed ? '#4CAF50' : '#FFFFFF')

删除线效果
.decoration({
type: task.completed ? TextDecorationType.LineThrough : TextDecorationType.None
})

交互逻辑
onClick:绑定按钮点击事件onChange:监听输入框变化onSubmit:键盘回车提交任务.enabled():控制按钮可用性,防止空提交
ArkUI List 核心技术解析
声明式渲染机制
ArkUI 的 List 组件采用声明式编程模型。开发者只需描述“UI 应该是什么样子”,无需手动操作 DOM。
- 数据驱动渲染:
@State数据更新 → ForEach 自动刷新 UI - 虚拟化性能优化:只渲染可视区域内列表项,滚动流畅
List({ space: 8 }) {
ForEach(this.tasks, (task: TaskItem) => {
ListItem() {
// 列表项内容
}
}, (task: TaskItem) => task.id.toString())
}
响应式状态管理
@State 自动监听数组和对象的变化,无需手动刷新:
- 用户点击“添加”
addTask()中this.tasks.push(newTask)- ArkUI 检测到变化
- 自动刷新
ForEach区域 - UI 实时更新
组件化与复用
通过 @Builder 封装复杂 UI:
@Builder
buildTaskItem(task: TaskItem, index: number) {
// 列表项布局逻辑
}
- 提升代码可读性
- 降低耦合,便于维护
- 有利于性能优化
完整实现代码
interface TaskItem {
id: number
title: string
completed: boolean
createTime: string
}
@Entry
@Component
struct Index {
@State tasks: TaskItem[] = [
{ id: 1, title: '学习 ArkUI List 组件', completed: false, createTime: '2024-10-15' },
{ id: 2, title: '编写技术博客', completed: true, createTime: '2024-10-14' },
{ id: 3, title: '优化应用性能', completed: false, createTime: '2024-10-13' }
]
@State newTaskTitle: string = ''
@State filterType: string = 'all'
build() {
Column({ space: 20 }) {
// 头部区域
this.buildHeader()
// 添加任务区域
this.buildAddTaskSection()
// 筛选标签
this.buildFilterTabs()
// 任务列表
this.buildTaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F8F9FA')
.padding({ top: 50 })
}
@Builder
buildHeader() {
Row() {
Text('我的任务清单')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#1976D2')
Blank()
Text(`${this.getCompletedCount()}/${this.tasks.length}`)
.fontSize(16)
.fontColor('#666666')
.backgroundColor('#E8F5E8')
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.borderRadius(12)
}
.width('90%')
.margin({ bottom: 10 })
}
@Builder
buildAddTaskSection() {
Row({ space: 10 }) {
TextInput({ placeholder: '输入新任务', text: this.newTaskTitle })
.flexGrow(1)
.onChange((value) => {
this.newTaskTitle = value
})
.onSubmit(() => this.addTask())
Button('添加')
.backgroundColor('#4CAF50')
.onClick(() => this.addTask())
.enabled(this.newTaskTitle.trim().length > 0)
}
.width('90%')
.margin({ bottom: 10 })
}
@Builder
buildFilterTabs() {
Row({ space: 12 }) {
this.buildFilterTab('all', '全部')
this.buildFilterTab('pending', '待完成')
this.buildFilterTab('completed', '已完成')
}
.width('90%')
.justifyContent(FlexAlign.Center)
.margin({ bottom: 10 })
}
@Builder
buildFilterTab(type: string, label: string) {
Text(label)
.fontSize(14)
.fontColor(this.filterType === type ? '#FFFFFF' : '#666666')
.backgroundColor(this.filterType === type ? '#007AFF' : '#F0F0F0')
.padding({ left: 16, right: 16, top: 8, bottom: 8 })
.borderRadius(16)
.onClick(() => this.filterType = type)
}
@Builder
buildTaskList() {
List({ space: 8 }) {
ForEach(this.getFilteredTasks(), (task: TaskItem, index: number) => {
ListItem() {
this.buildTaskItem(task, index)
}
.backgroundColor('#FFFFFF')
.borderRadius(12)
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
.shadow({ radius: 2, color: '#E0E0E0' })
}, (task: TaskItem) => task.id.toString())
}
.width('90%')
.layoutWeight(1)
.scrollBar(BarState.Auto)
.divider({
strokeWidth: 1,
color: '#F0F0F0',
startMargin: 16,
endMargin: 16
})
}
@Builder
buildTaskItem(task: TaskItem, index: number) {
Row({ space: 12 }) {
// 完成状态指示器(用容器画一个圆点,避免 Circle.fill/stroke 签名不匹配)
// 已完成:实心绿色圆;未完成:白底灰边圆
Stack() {
// 空内容,只用外观
}
.width(20)
.height(20)
.borderRadius(10)
.backgroundColor(task.completed ? '#4CAF50' : '#FFFFFF')
.border({ width: 2, color: task.completed ? '#4CAF50' : '#CCCCCC' })
.onClick(() => this.toggleTaskStatus(task.id))
// 任务内容
Column({ space: 4 }) {
Text(task.title)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor(task.completed ? '#999999' : '#1A1A1A')
.decoration({
type: task.completed ? TextDecorationType.LineThrough : TextDecorationType.None
})
.maxLines(2)
//新签名:传对象
.textOverflow({ overflow: TextOverflow.Ellipsis })
Text(task.createTime)
.fontSize(12)
.fontColor('#999999')
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
// 删除按钮
Button('删除')
.fontSize(12)
.fontColor('#FFFFFF')
.backgroundColor('#FF3B30')
.borderRadius(6)
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.onClick(() => this.deleteTask(task.id))
}
.width('100%')
.alignItems(VerticalAlign.Center)
}
// 数据操作方法
addTask() {
if (this.newTaskTitle.trim().length > 0) {
const newTask: TaskItem = {
id: Date.now(),
title: this.newTaskTitle.trim(),
completed: false,
createTime: new Date().toISOString().split('T')[0]
}
this.tasks.push(newTask)
this.newTaskTitle = ''
}
}
toggleTaskStatus(taskId: number) {
const taskIndex = this.tasks.findIndex(task => task.id === taskId)
if (taskIndex !== -1) {
this.tasks[taskIndex].completed = !this.tasks[taskIndex].completed
}
}
deleteTask(taskId: number) {
this.tasks = this.tasks.filter(task => task.id !== taskId)
}
// 辅助方法
getFilteredTasks(): TaskItem[] {
switch (this.filterType) {
case 'pending':
case 'pending':
return this.tasks.filter(task => !task.completed)
case 'completed':
return this.tasks.filter(task => task.completed)
default:
return this.tasks
}
}
getCompletedCount(): number {
return this.tasks.filter(task => task.completed).length
}
}
总结
本文以一个任务管理小应用为例,展示了 HarmonyOS 上 ArkTS 与 ArkUI 的实战效果。声明式 UI 搭配响应式状态,让界面更新更省心;@State 自动触发渲染,配合列表虚拟化保证大数据量下的流畅;用 @Builder 做模块化,代码更清爽、易复用。 做小项目能快起来,做大项目也能稳住——在 HarmonyOS 上,“声明式 + 响应式”会是更省心的路子。

更多推荐




所有评论(0)