鸿蒙ArkTS零基础实战:极简备忘录开发
前言
大家好,今天给大家带来一篇 OpenHarmony ArkTS 零基础实战项目——极简备忘录开发教程。
在鸿蒙应用开发的入门学习阶段,备忘录是最经典、最适合新手练手的项目之一。它涵盖了鸿蒙开发中状态管理、UI布局、列表渲染、点击事件、数组数据操作等核心高频知识点,几乎覆盖了ArkTS声明式UI的基础核心。
本文将从零开始,带大家完整实现一款具备 添加备忘、单条删除、一键清空、输入框限制 功能的原生鸿蒙备忘录应用。
整篇文章代码可直接复制运行,无需额外权限、无需数据库、无需网络请求,适配 API9 / API10 主流版本,适合新手入门、课程作业、练手项目、期末实训。

一、项目效果预览
本项目最终实现功能如下:
- 文本输入:支持用户自定义输入备忘内容
- 添加备忘:非空校验,禁止空白内容提交
- 逐条渲染列表:新增内容实时展示在页面
- 单条删除:每条备忘录独立删除,精准删除对应数据
- 一键清空:一键清除所有备忘录数据
- 自动清空输入框:添加完成后输入框自动置空,交互体验完整
- 自适应布局:适配手机全屏展示,布局整洁美观
整体逻辑为 数据驱动视图,完全符合鸿蒙声明式UI的设计思想。
二、技术栈与开发环境
2.1 核心技术
- 开发语言:ArkTS(TypeScript超集)
- UI框架:ArkUI 声明式UI
- 核心技术点:状态变量、组件组合、List列表、ForEach渲染、数组操作、点击事件、表单输入绑定
2.2 开发环境
- 开发工具:DevEco Studio
- 适配SDK:HarmonyOS API9 / API10
- 运行设备:模拟器 / 真机
三、整体开发思路
在正式写代码之前,我们先梳理整个备忘录的业务逻辑,新手写项目一定要先理清思路再写代码。
3.1 数据层设计
- 定义备忘录数据结构(每条备忘录包含唯一ID + 文本内容)
- 定义数组列表,统一存储所有备忘录数据
- 定义自增ID,保证每一条备忘录ID唯一,用于精准删除
3.2 视图层设计
页面整体分为三大模块:
- 顶部输入模块:TextInput输入框 + 添加按钮
- 中间列表模块:List列表渲染所有备忘录条目
- 底部功能模块:一键清空全部备忘录按钮
3.3 业务逻辑设计
- 添加逻辑:获取输入内容 -> 去除首尾空格 -> 非空判断 -> 新增数据 -> 清空输入框
- 删除逻辑:根据唯一ID过滤数组,删除指定条目
- 清空逻辑:直接置空数组,视图自动刷新
四、完整可运行源码
下面直接放出完整可运行源码,可直接替换页面文件运行:
代码解析:鸿蒙备忘录应用实现
数据结构定义
interface NoteItem {
id: number,
content: string
}
定义了备忘录条目的数据结构,包含唯一标识id和内容content两个字段。
组件状态管理
@State inputText: string = ""
@State noteList: NoteItem[] = []
private noteId: number = 1
inputText:绑定输入框内容的状态变量noteList:存储所有备忘录条目的状态数组noteId:自增ID生成器,保证每条记录唯一性
核心功能方法
// 添加新备忘
addNote(): void {
const temp = this.inputText.trim()
if (temp.length === 0) return
this.noteList.push({
id: this.noteId,
content: temp
})
this.noteId++
this.inputText = ""
}
// 删除单条备忘
delNote(id: number): void {
this.noteList = this.noteList.filter(
item => item.id !== id
)
}
// 清空所有备忘
clearAll(): void {
this.noteList = []
}
UI布局结构
Column() {
// 输入区域
Row() {
TextInput().width("80%")
Button("添加")
}
// 列表区域
List() {
ForEach(this.noteList, (item) => {
ListItem() {
Row() {
Text(item.content)
Button("删除")
}
}
})
}
// 底部按钮
Button("清空所有备忘")
}
关键实现细节
数据绑定机制
TextInput通过onChange事件实时更新inputText状态noteList数组变化自动触发ForEach重新渲染列表
交互设计要点
- 添加操作需检测非空输入(
.trim().length > 0) - 删除采用数组过滤方式更新状态
- 列表项使用
Row布局实现内容与按钮并排
样式处理技巧
- 宽度使用百分比布局(
width("80%")) - 设置
layoutWeight(1)让文本区域自动填充剩余空间 - 全局设置白色背景(
backgroundColor("#ffffff"))
扩展建议
数据持久化 可添加LocalStorage支持:
@StorageLink('notes') storageList: NoteItem[] = []
交互增强
- 添加长按编辑功能
- 实现滑动删除手势
- 增加重要程度标记
UI优化
- 添加分割线样式
- 实现完成状态切换
- 增加动画效果
interface NoteItem {
id: number,
content: string
}
@Entry
@Component
struct NoteDemo {
@State inputText: string = ""
@State noteList: NoteItem[] = []
private noteId: number = 1
// 添加备忘
addNote(): void {
let temp = this.inputText.trim()
if (temp.length === 0) {
return
}
this.noteList.push({ id: this.noteId, content: temp })
this.noteId++
this.inputText = ""
}
// 删除单条
delNote(id: number): void {
this.noteList = this.noteList.filter(item => item.id !== id)
}
// 清空全部
clearAll(): void {
this.noteList = []
}
build() {
Column() {
// 顶部输入区
Row() {
TextInput({ text: this.inputText, placeholder: "请输入备忘内容" })
.width("80%")
.onChange((val: string) => {
this.inputText = val
})
Button("添加")
.onClick(() => {
this.addNote()
})
}
.width("95%")
.margin({ top: 20 })
// 备忘列表区域
List({ space: 10 }) {
ForEach(this.noteList, (item: NoteItem) => {
ListItem() {
Row() {
Text(item.content)
.layoutWeight(1)
Button("删除")
.fontSize(14)
.onClick(() => this.delNote(item.id))
}
.width("100%")
.padding(10)
}
})
}
.width("95%")
.layoutWeight(1)
.margin({ top: 15 })
// 底部清空按钮
Button("清空所有备忘")
.width("90%")
.margin({ bottom: 20 })
.onClick(() => this.clearAll())
}
.width("100%")
.height("100%")
.backgroundColor("#ffffff")
}
}
五、代码逐模块深度解析
5.1 自定义数据结构 interface
interface NoteItem {
id: number,
content: string
}
解析:
在ArkTS中,interface用于自定义数据类型,规范数据格式。
每条备忘录固定包含两个字段:
- id:数值类型,唯一标识,用于精准删除
- content:字符串类型,存储备忘文本内容
优势:
- 规范代码格式,避免乱写数据
- 代码可读性极高
- 配合TS语法,自带类型校验,减少报错
5.2 状态变量解析
@State inputText: string = ""
@State noteList: NoteItem[] = []
private noteId: number = 1
1. @State 核心知识点
@State 是鸿蒙最基础、最重要的 状态装饰器。
被 @State 修饰的变量具备:
- 数据变化 → 页面自动刷新
- 双向响应能力
- 驱动UI更新
2. 变量作用
- inputText:绑定输入框实时内容
- noteList:全局备忘录数据源,页面所有列表全部由该数组渲染
- noteId:私有变量,不参与UI刷新,只做数据自增
5.3 添加备忘逻辑 addNote
addNote(): void {
let temp = this.inputText.trim()
if (temp.length === 0) {
return
}
this.noteList.push({ id: this.noteId, content: temp })
this.noteId++
this.inputText = ""
}
业务逻辑拆解:
- trim():去除用户输入的首尾空格,防止全空格内容占位
- 非空拦截:如果处理后内容为空,直接终止函数,不允许空数据
- push新增对象,存入当前ID和文本
- ID自增,保证下一条数据ID永不重复
- 清空输入框,优化用户体验
5.4 单条删除逻辑 delNote
|
delNote(id: number): void { this.noteList = this.noteList.filter(item => item.id !== id) } |
核心原理:数组过滤
filter 会遍历原数组,保留符合条件的数据。
逻辑:
- 保留所有 id 不等于 当前点击id 的数据
- 等于当前id的数据直接剔除
- 重新赋值给状态数组 → 视图自动刷新 → 实现删除
5.5 清空全部逻辑 clearAll
clearAll() 方法解析
clearAll(): void { this.noteList = [] } 是一个用于清空数组或列表的方法。以下是对该方法的详细说明:
方法功能
- 该方法将
noteList属性重置为空数组[],清空其中所有元素。 - 返回类型为
void,表示该方法不返回任何值。
代码示例
class NoteManager {
private noteList: any[] = [];
clearAll(): void {
this.noteList = [];
}
}
使用场景
- 需要清空一个数组或列表时调用此方法。
- 适用于重置数据、初始化状态或清除临时存储的场景。
注意事项
- 直接赋值空数组
[]会创建一个新的数组实例,原数组的引用将被替换。 - 如果其他部分代码持有对原数组的引用,这些引用不会自动更新,可能导致不一致状态。

5.6 页面布局结构解析
整体容器 Column
整个页面采用 Column 垂直布局,从上到下依次排列:输入区 → 列表区 → 按钮区。
顶部 Row 输入行
Row 水平布局:左边输入框、右边按钮,经典组合布局。
List + ForEach 列表渲染
List:鸿蒙高性能滚动列表组件,适合长列表展示
ForEach:循环渲染数组数据,批量生成 ListItem
layoutWeight(1) 让列表自动占满剩余屏幕高度,布局非常规整。
六、核心知识点总结(面试/考试重点)
6.1 @State 状态管理机制
- 组件内部私有状态
- 数据改变驱动视图自动刷新
- 仅当前组件生效
6.2 声明式UI核心思想
数据驱动视图
我们不操作DOM、不操作UI,只修改数据,页面自动变化。
命令式:操作UI → 修改内容
声明式:修改数据 → UI自动更新
6.3 ForEach 渲染规则
- 必须遍历数组
- 必须返回组件
- 数据变化自动刷新列表
6.4 数组常用增删操作
- 新增:push
- 删除指定项:filter
- 清空:重新赋值空数组
七、项目常见BUG与解决方案
问题1:可以输入空白空格保存
原因:未做 trim 处理
解决:添加前先 trim() 去除首尾空格,判断长度
问题2:删除错乱、删除不对条目
原因:未使用唯一ID,误用索引删除
本项目优势:采用独立自增ID,永远不会错乱
问题3:添加完成输入框不消失
解决:手动置空 this.inputText = ""
问题4:列表无法滚动
解决:给 List 设置 layoutWeight(1) 撑满剩余区域
八、项目拓展升级思路(适合二次开发)
如果需要把该项目升级为高级版备忘录,可以拓展以下功能:
- 本地持久化存储:使用 Preferences 保存数据,重启应用不丢失
- 编辑功能:点击条目修改原有备忘内容
- 时间戳记录:新增创建时间、修改时间
- 置顶功能:重要备忘录置顶
- 删除动画:添加组件过渡动画
- 分类标签:给备忘录添加标签分类
- 搜索功能:关键词检索备忘录


九、结语
本篇文章完整实现了 ArkTS 极简备忘录,涵盖了鸿蒙开发最基础、最核心的知识点。
新手学鸿蒙,不要一上来就撸复杂项目,把备忘录、计数器、待办清单这类基础项目吃透,就能彻底掌握 状态管理 + 列表渲染 + 事件交互 的核心逻辑,后续复杂项目上手会非常快。
更多推荐


所有评论(0)