手机本地待办也能跑:用 ArkTS 写一个待办卡片列表

举报
静水流深-云海 发表于 2026/09/26 22:33:18 2026/09/26
【摘要】 用 ArkTS + ArkUI 写鸿蒙待办列表:@State 管待办数组、build() 声明式描述界面、ForEach 渲染卡片,输入框 onchange 写回、添加 push/完成翻 done/删除 filter 重赋值,界面自动更新;附 @Builder 抽卡片、稳定 key、受控输入等注意点,纯本地状态跑模拟器。

学鸿蒙应用开发,第一个练手项目往往就是"待办清单"——它覆盖了状态管理、列表渲染、用户输入、删除这几样最常用的能力。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 保顺序。纯本地状态跑在模拟器就能看效果,理解这套声明式思路后,加持久化、加分类都很自然。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。