手机本地待办也能跑:用 ArkTS 写一个待办卡片列表
学鸿蒙应用开发,第一个练手项目往往就是"待办清单"——它覆盖了状态管理、列表渲染、用户输入、删除这几样最常用的能力。ArkTS 是鸿蒙的主力开发语言,用声明式 UI(ArkUI)写界面:你描述"界面长什么样、数据是什么",框架负责渲染和更新。本文用纯本地状态(不联网、不存数据库)实现一个能增、能勾掉、能删的待办列表,跑在 DevEco Studio 的模拟器里。
和命令式 UI(先拿到 view、再手动改文字)不同,声明式写法的好处是"界面是数据的函数":数据变了,界面自动跟着变,你不用自己找哪个控件该更新。待办这种"增删改都反映在列表上"的场景,正好能把这套思路体会透,是入门鸿蒙性价比最高的一小块。
一、先定义数据和页面骨架
一个待办就是一条带"内容"和"是否完成"的记录。我们用一个接口描述它,页面用一个 @State 数组保存全部待办:
// TodoPage.ets
interface TodoItem {
id: number;
text: string;
done: boolean;
}
@Entry
@Component
struct TodoPage {
@State todos: TodoItem[] = [];
@State draft: string = ""; // 输入框里的临时文字
private nextId: number = 1;
}
@State 是 ArkTS 的状态装饰器:被它标记的数据一变,用到它的界面会自动重渲染。todos 就是待办列表,draft 是输入框的临时值,nextId 用来给新待办发号。
二、搭界面:输入框、按钮、列表
ArkUI 用嵌套的组件描述布局。顶部一个输入框加"添加"按钮,下面用 ForEach 把每条待办渲染成一张卡片:
build() {
Column({ space: 12 }) {
Row({ space: 8 }) {
TextInput({ placeholder: "写点要做的事", text: this.draft })
.onChange(v => this.draft = v)
Button("添加")
.onClick(() => this.addTodo())
}
.padding(12)
List() {
ForEach(this.todos, (item: TodoItem) => {
ListItem() {
this.todoCard(item)
}
}, (item: TodoItem) => item.id.toString())
}
}
.width("100%")
}
TextInput 的 onChange 把输入实时写回 draft;Button 点击调用 addTodo 把 draft 变成一条新待办。List + ForEach 把 todos 数组映射成一组卡片,第三个参数是"键",用 id 保证列表更新时对得上号。
三、增、勾、删三个动作
逻辑都在组件方法里,改的是 @State 的 todos,界面自动跟着变:
private addTodo() {
const text = this.draft.trim();
if (!text) return; // 空的就不加
this.todos.push({ id: this.nextId++, text, done: false });
this.draft = ""; // 加完清空输入框
}
private toggle(item: TodoItem) {
item.done = !item.done; // 切换完成状态
}
private remove(item: TodoItem) {
this.todos = this.todos.filter(t => t.id !== item.id);
}
addTodo 做非空校验,避免加空白待办;toggle 翻 done;remove 用 filter 返回新数组。注意 remove 是"整个数组替换",这样 @State 才能感知到变化去重渲染(直接 splice 有时不触发更新,用赋值更稳)。
四、把卡片画出来
todoCard 是一个子组件,展示文字、完成态样式,并绑定勾选和删除:
@Builder
private todoCard(item: TodoItem) {
Row({ space: 10 }) {
Text(item.text)
.fontSize(16)
.decoration({ type: item.done ? TextDecorationType.LineThrough : TextDecorationType.None })
.fontColor(item.done ? "#999999" : "#1f2937")
Blank()
Button(item.done ? "已做" : "完成")
.onClick(() => this.toggle(item))
Button("删")
.onClick(() => this.remove(item))
}
.width("100%")
.padding(12)
.backgroundColor("#f1f5f9")
.borderRadius(8)
}
@Builder 是 ArkTS 里抽"可复用界面片段"的方式。完成的待办加删除线、变灰,一眼能区分。Blank() 把按钮顶到右边。
五、几个要注意的点
第一,@State 只能修饰组件里的成员变量,且最好是"能被框架追踪"的普通类型或数组/对象;深层嵌套对象改属性有时不触发更新,必要时整体重新赋值。第二,ForEach 必须给稳定 key(这里是 id),不然增删后界面顺序会乱。第三,输入框用受控写法(text 绑定 draft + onChange 回写),比读 ref 更顺。第四,模拟器里默认有数据存储概念,但本例纯内存,关掉应用数据就没了——要持久化可接 Preferences 或关系型数据库,那是下一步。第五,Button 默认有圆角和底色,想改样式用 backgroundColor / fontSize 等链式属性。第六,组件名和文件名约定以 DevEco 模板为准,ets 后缀是 ArkTS 页面。
六、小结
用 ArkTS + ArkUI 写待办列表,核心是 @State 管数据、build() 描述界面、ForEach 渲染列表:输入框 onchange 写回 draft,添加用 push、完成翻 done、删除用 filter 重赋值,界面自动更新。@Builder 抽卡片、稳定 key 保顺序。纯本地状态跑在模拟器就能看效果,理解这套声明式思路后,加持久化、加分类都很自然。
- 点赞
- 收藏
- 关注作者
评论(0)