# 备忘录应用开发实战:HarmonyOS ArkTS 快速记事本应用解析

一、应用概述

备忘录应用是移动设备上最经典、最基础的生产力工具之一。本文将以 HarmonyOS 原生开发框架 ArkTS 为基础,详细解析一个轻量级备忘录应用(Quick Memo)的完整开发过程。该应用支持用户快速记录文字内容,自动添加时间戳,并具备添加与删除备忘录的核心功能。

1.1 功能特性

  • 快速记录:用户可以在输入框中输入任意文本内容,点击添加按钮即可生成一条备忘录记录
  • 自动时间戳 :每条备忘录在创建时自动记录当前时间,并按照 YYYY-MM-DD HH:mm 的格式呈现
  • 列表展示:所有备忘录以列表形式清晰展示,最新添加的记录排列在最上方
  • 滑动删除:支持左滑或点击删除按钮移除指定备忘录
  • 数据持久化:利用 HarmonyOS 的本地存储能力,确保重启应用后数据不丢失

1.2 适用场景

  • 日常灵感记录
  • 待办事项快速录入
  • 购物清单管理
  • 会议要点摘录

1.3 技术亮点

本应用虽然功能简洁,却完整展现了 ArkTS 声明式 UI 开发的核心理念,包括组件状态管理、列表渲染、事件绑定、数据持久化等关键技术点,是 ArkTS 入门学习的绝佳案例。


二、技术架构

2.1 整体架构概览

本应用采用 HarmonyOS 推荐的单页面(单 Ability)架构,以 @Entry 装饰的主页面作为唯一入口,内部通过 @Component 拆分为多个功能模块。整体架构分为三层:

复制代码
┌─────────────────────────────────────┐
│            UI 表示层                  │
│  (MainPage / MemoItem / AddMemoBar)  │
├─────────────────────────────────────┤
│           状态管理层                  │
│  (@State / @Prop / @Link 装饰器)     │
├─────────────────────────────────────┤
│           数据持久层                  │
│  (Preferences / AppStorage)          │
└─────────────────────────────────────┘

2.2 核心数据结构

备忘录的数据模型定义如下:

arkts 复制代码
interface Memo {
  id: string;        // 唯一标识符
  content: string;   // 备忘录内容
  timestamp: number; // 创建时间(时间戳)
}

每个 Memo 对象通过 id 字段实现唯一标识,确保在删除和更新操作中能精确定位目标记录。timestamp 字段存储 Unix 时间戳,便于后续按时间排序和格式化显示。

2.3 组件树结构

复制代码
@Entry MainPage
  ├── Column (主容器)
  │   ├── Text (标题栏)
  │   ├── Row (输入区域)
  │   │   ├── TextInput (文本输入框)
  │   │   └── Button (添加按钮)
  │   └── List (备忘录列表)
  │       └── ForEach → MemoItem (自定义列表项)
  │           ├── Text (内容)
  │           ├── Text (时间戳)
  │           └── Button (删除)

三、核心代码分析

3.1 数据模型与状态管理

备忘录的数据模型使用 interface 定义,确保类型的强约束性。所有备忘录数据通过 @State 装饰器管理,当数据发生变化时,框架自动重新渲染 UI。

arkts 复制代码
// 备忘录数据模型
interface Memo {
  id: string;
  content: string;
  timestamp: number;
}

@Entry
@Component
struct MemoApp {
  // 使用 @State 管理备忘录列表,驱动 UI 更新
  @State private memoList: Memo[] = [];
  @State private inputContent: string = '';
  
  // 格式化时间戳为可读字符串
  private formatTime(timestamp: number): string {
    const date = new Date(timestamp);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hour = String(date.getHours()).padStart(2, '0');
    const minute = String(date.getMinutes()).padStart(2, '0');
    return `${year}-${month}-${day} ${hour}:${minute}`;
  }
}

@State 是 ArkTS 中最基础的状态装饰器。当 memoList 的内容发生变化(增删改)时,所有依赖于该数据的 UI 组件会自动重新渲染。这种声明式编程方式大幅简化了传统的命令式 DOM 操作,让开发者可以专注于业务逻辑本身。

3.2 添加备忘录功能

备忘录的添加操作需要完成三步工作:生成唯一 ID、获取当前时间戳、将新记录插入列表头部。

arkts 复制代码
// 添加备忘录
addMemo() {
  if (this.inputContent.trim() === '') {
    // 空内容不添加,提升用户体验
    return;
  }
  
  // 生成唯一 ID
  const newMemo: Memo = {
    id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
    content: this.inputContent.trim(),
    timestamp: Date.now()
  };
  
  // 插入到列表头部(最新在上)
  this.memoList.unshift(newMemo);
  // 清空输入框
  this.inputContent = '';
  // 持久化存储
  this.saveData();
}

关键设计考量

  • ID 生成策略 :使用 Date.now() 结合随机数,确保在多设备、多线程环境下 ID 的唯一性
  • 空值校验:在添加前校验内容是否为空,避免产生无意义的空记录
  • 头部插入 :使用 unshift 而非 push,保证最新记录显示在列表最上方
  • 自动清空:添加成功后立即清空输入框,方便用户连续记录

3.3 删除备忘录功能

删除操作提供两种交互方式:点击删除按钮和左滑删除手势。

arkts 复制代码
// 删除备忘录
deleteMemo(memoId: string) {
  // 根据 ID 过滤出要保留的记录
  this.memoList = this.memoList.filter(item => item.id !== memoId);
  // 同步持久化数据
  this.saveData();
}

// UI 中的删除按钮
Button('删除')
  .fontColor(Color.Red)
  .fontSize(14)
  .onClick(() => {
    this.deleteMemo(item.id);
  })

使用数组的 filter 方法删除记录是一种函数式编程的实践,它不会修改原数组,而是返回一个新数组。ArkTS 的状态管理机制能检测到这种变化并触发 UI 更新。

3.4 列表渲染与 ForEach

备忘录列表使用 ForEach 指令进行循环渲染,这是 ArkTS 中最常用的列表渲染方式。

arkts 复制代码
List({ space: 12 }) {
  ForEach(this.memoList, (item: Memo, index: number) => {
    ListItem() {
      // 自定义备忘录卡片
      Column() {
        Text(item.content)
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
          .width('100%')
          .textAlign(TextAlign.Start)
        
        Text(this.formatTime(item.timestamp))
          .fontSize(12)
          .fontColor(Color.Gray)
          .width('100%')
          .textAlign(TextAlign.End)
          .margin({ top: 8 })
        
        // 删除按钮
        Button('删除')
          .fontColor(Color.Red)
          .fontSize(14)
          .onClick(() => {
            this.deleteMemo(item.id);
          })
          .alignSelf(ItemAlign.End)
          .margin({ top: 4 })
      }
      .padding(16)
      .backgroundColor(Color.White)
      .borderRadius(12)
      .shadow({
        radius: 4,
        color: 'rgba(0, 0, 0, 0.08)',
        offsetX: 0,
        offsetY: 2
      })
      .width('100%')
    }
    // 添加滑动删除支持
    .swipeAction({
      end: {
        builder: () => {
          Button('删除')
            .width(80)
            .height('100%')
            .backgroundColor(Color.Red)
            .fontColor(Color.White)
            .onClick(() => {
              this.deleteMemo(item.id);
            })
        }
      }
    })
  }, (item: Memo) => item.id)
}

ForEach 的 key 生成器 :第三个参数 (item: Memo) => item.id 是 key 生成器,它告诉框架如何唯一标识每个列表项。使用 item.id 作为 key 可以确保列表在增删操作时能够高效地复用和重排组件,避免不必要的全量重建。

3.5 数据持久化

利用 HarmonyOS 的 Preferences 轻量级键值数据库实现数据持久化:

arkts 复制代码
import preferences from '@ohos.data.preferences';

// 保存数据到本地
async saveData() {
  const context = getContext(this);
  const pref = await preferences.getPreferences(context, 'memo_db');
  // 将对象数组转换为 JSON 字符串存储
  await pref.put('memo_list', JSON.stringify(this.memoList));
  await pref.flush();
}

// 从本地加载数据
async loadData() {
  const context = getContext(this);
  const pref = await preferences.getPreferences(context, 'memo_db');
  const jsonStr = await pref.get('memo_list', '[]');
  this.memoList = JSON.parse(jsonStr as string);
}

持久化流程

  1. 通过 getPreferences 获取或创建数据库实例
  2. 使用 put 方法存储序列化后的数据
  3. 调用 flush 确保数据写入磁盘
  4. 读取时使用 get 方法获取 JSON 字符串,再反序列化为对象数组

四、HarmonyOS关键技术应用

4.1 声明式 UI 与状态管理

HarmonyOS 的 ArkUI 框架采用了声明式 UI 范式,这与传统的命令式 UI 有本质区别。在声明式 UI 中,开发者只需描述 UI 的最终状态,框架负责处理状态变化后的 UI 更新。

特性 传统命令式 声明式(ArkTS)
编程方式 手动操作 DOM 描述 UI 状态
状态同步 手动同步 自动追踪
代码量 较多 精简
可维护性 一般 优秀

@State 装饰器是状态管理的核心,其工作原理可概括为:

  1. 开发者用 @State 标记一个变量为响应式数据
  2. 当该变量的值发生变化时,框架自动标记所有依赖它的组件为"脏"状态
  3. 框架在下一个渲染周期中,重新执行所有脏组件的 build 方法
  4. 通过虚拟 DOM 的 diff 算法,仅更新实际变化的 UI 部分

4.2 List 组件的性能优化

List 组件是 HarmonyOS 中高效的列表容器,它内置了以下优化机制:

  • 懒加载(Lazy Loading):只渲染可见区域的列表项,不可见区域的内容不会创建对应的组件实例
  • 组件复用(Component Reuse):当用户滚动列表时,移出屏幕的组件实例会被回收并复用给新进入屏幕的列表项
  • 缓存池(Cache Pool):在可见区域上下各预缓存一定数量的列表项,确保快速滚动时的流畅体验
arkts 复制代码
List({ space: 12, scroller: this.scroller }) {
  // 列表内容
}
.layoutWeight(1)
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.scrollBar(BarState.Off)

4.3 自定义组件封装

将备忘录卡片封装为独立的 @Component,提升了代码的复用性和可维护性:

arkts 复制代码
@Component
struct MemoItem {
  private memo: Memo;
  private onDelete: () => void;
  
  build() {
    Column() {
      Text(this.memo.content)
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
      
      Text(this.formatTime(this.memo.timestamp))
        .fontSize(12)
        .fontColor(Color.Gray)
        .margin({ top: 8 })
      
      Button('删除')
        .fontColor(Color.Red)
        .fontSize(14)
        .onClick(() => {
          this.onDelete();
        })
    }
    .padding(16)
    .backgroundColor(Color.White)
    .borderRadius(12)
  }
  
  private formatTime(timestamp: number): string {
    // 时间格式化逻辑
  }
}

自定义组件的优势:

  • 封装性:将 UI 结构和样式封装在组件内部,对外只暴露必要的属性和回调
  • 复用性:同一组件可在不同页面或同一页面的不同位置重复使用
  • 可测试性:独立组件便于进行单元测试和 UI 测试

五、UI设计与交互

5.1 视觉设计

本应用的视觉设计遵循 Material Design 设计规范,同时融入 HarmonyOS 的设计语言特点:

配色方案

  • 主色调:系统蓝色(#0A59F7
  • 背景色:浅灰色(#F5F5F5
  • 卡片背景:纯白色(#FFFFFF
  • 文字色:深灰色(#333333
  • 辅助色:灰色(#999999)用于时间戳
  • 警示色:红色(#FF0000)用于删除操作

卡片设计

每条备忘录以卡片形式呈现,圆角 12px,带有微弱的阴影效果,营造出层次感和立体感。卡片内左上方显示备忘录内容,右下方显示创建时间,布局清晰直观。

5.2 交互反馈

  • 添加动画:新备忘录添加时,列表项以淡入动画呈现
  • 删除反馈:删除按钮点击后,列表项以淡出动画消失
  • 滑动删除:列表项支持左滑手势,露出删除按钮,提升操作效率
  • 空状态提示:当列表为空时,显示"暂无备忘录"的友好提示

5.3 自适应布局

应用使用 ArkTS 的弹性布局(FlexColumn)实现自适应,在不同屏幕尺寸下均有良好表现。

arkts 复制代码
Column() {
  // 标题区域
  Text('备忘录')
    .fontSize(24)
    .fontWeight(FontWeight.Bold)
    .width('100%')
    .padding(16)
  
  // 输入区域
  Row() {
    TextInput({ placeholder: '输入备忘录内容...' })
      .layoutWeight(1)
      .height(48)
      .backgroundColor(Color.White)
      .borderRadius(8)
    
    Button('添加')
      .width(64)
      .height(48)
      .margin({ left: 12 })
      .backgroundColor('#0A59F7')
      .fontColor(Color.White)
      .borderRadius(8)
  }
  .padding({ left: 16, right: 16, bottom: 12 })
  
  // 列表区域
  List({ space: 12 }) {
    // ...
  }
  .layoutWeight(1)
  .padding(16)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')

六、性能优化与最佳实践

6.1 性能优化策略

6.1.1 减少不必要的重新渲染

在使用 @State 时,需要注意避免触发不必要的 UI 更新:

arkts 复制代码
// ❌ 不良实践:每次添加都触发全列表重绘
this.memoList = [...this.memoList, newMemo];

// ✅ 最佳实践:使用数组方法并配合 key 生成器
this.memoList.unshift(newMemo);
// ForEach 配合唯一 key 可精确定位需要更新的项
6.1.2 合理使用计算属性

对于需要复杂计算的数据,使用 @Computed 或 getter 方法缓存计算结果:

arkts 复制代码
// 使用 getter 计算统计数据
get totalMemos(): number {
  return this.memoList.length;
}

get todayMemos(): number {
  const today = new Date().toDateString();
  return this.memoList.filter(item => 
    new Date(item.timestamp).toDateString() === today
  ).length;
}
6.1.3 数据持久化优化

避免频繁的磁盘写入操作,可以采用防抖(Debounce)策略:

arkts 复制代码
private saveTimer: number | null = null;

debounceSave() {
  if (this.saveTimer) {
    clearTimeout(this.saveTimer);
  }
  this.saveTimer = setTimeout(() => {
    this.saveData();
    this.saveTimer = null;
  }, 500); // 500ms 防抖
}

6.2 最佳实践总结

6.2.1 代码组织规范
复制代码
src/
├── main/
│   ├── ets/
│   │   ├── pages/
│   │   │   └── Index.ets          # 主页面
│   │   ├── components/
│   │   │   ├── MemoItem.ets       # 备忘录卡片组件
│   │   │   └── AddMemoBar.ets     # 添加栏组件
│   │   ├── model/
│   │   │   └── MemoModel.ets      # 数据模型定义
│   │   └── utils/
│   │       └── DateUtil.ets       # 工具函数
│   └── resources/
│       └── ...
6.2.2 状态提升原则

将共享状态提升到共同的父组件中,子组件通过 @Prop@Link 接收数据和回调:

arkts 复制代码
// 父组件管理状态
@State memoList: Memo[] = [];

build() {
  Column() {
    AddMemoBar({ onAdd: (content) => this.addMemo(content) })
    MemoList({ 
      memos: this.memoList, 
      onDelete: (id) => this.deleteMemo(id) 
    })
  }
}
6.2.3 错误处理与边界情况
arkts 复制代码
// 处理空列表情况
if (this.memoList.length === 0) {
  // 显示空状态
  Image($r('app.media.empty_illustration'))
    .width(200)
    .height(200)
  Text('暂无备忘录')
    .fontColor(Color.Gray)
    .fontSize(16)
}

// 处理输入过长的情况
if (this.inputContent.length > 500) {
  showToast('备忘录内容不能超过500字');
  return;
}

七、总结与扩展思路

7.1 项目总结

本文详细解析了基于 HarmonyOS ArkTS 框架开发的备忘录应用。通过本项目的学习,开发者可以掌握以下关键技术点:

  1. ArkTS 声明式 UI 开发 :理解 @State@Prop@Link 等装饰器的工作原理和使用场景
  2. 列表渲染与交互 :掌握 List + ForEach 的高效列表渲染方案
  3. 数据持久化:熟悉 HarmonyOS Preferences 轻量级数据库的使用
  4. 自定义组件设计:学会将 UI 拆分为可复用的自定义组件
  5. 交互体验优化:掌握动画、手势、反馈等交互设计要点

7.2 扩展思路

本应用作为基础版本,可以从以下几个方面进行扩展和增强:

7.2.1 功能增强
  • 分类管理:为备忘录添加分类标签,支持按分类筛选
  • 搜索功能:实现关键词搜索,快速定位目标记录
  • 富文本编辑:支持 Markdown 语法或富文本格式
  • 图片附件:支持为备忘录添加图片或语音附件
  • 云同步:利用 HarmonyOS 的分布式能力实现多设备数据同步
7.2.2 交互升级
  • 长按拖拽排序:通过拖拽手势改变备忘录顺序
  • 暗黑模式适配:响应系统暗黑模式,提供舒适的夜间使用体验
  • 小组件(Widget):开发 HarmonyOS 卡片小组件,在桌面直接查看和添加备忘录
  • 语音输入:集成语音识别能力,支持语音转文字记录
7.2.3 技术进阶
  • 原子化服务:将应用改造为 HarmonyOS 原子化服务,免安装即用
  • 跨端移植:利用 ArkTS 的多平台适配能力,将应用移植到平板和折叠屏设备
  • 性能监控:接入性能监控 SDK,持续优化应用性能
  • 单元测试:为关键业务逻辑编写单元测试,确保代码质量

7.3 学习建议

对于 HarmonyOS 初学者,建议按照以下路径学习本应用相关的技术点:

  1. 先理解 @State 状态管理机制,这是 ArkTS 开发的核心
  2. 掌握 List 组件的使用,包括懒加载和组件复用
  3. 学习 ForEach 的 key 生成器原理
  4. 理解自定义组件的生命周期和通信方式
  5. 最后研究数据持久化和性能优化方案

通过本项目的学习,开发者可以建立起 ArkTS 应用开发的基本框架思维,为进一步开发更复杂的 HarmonyOS 应用打下坚实基础。


项目代码已完整开源,开发者可以基于本文的代码示例进行二次开发和创新。HarmonyOS 生态正快速发展,掌握 ArkTS 开发技能将为开发者打开通往万物互联时代的大门。

相关推荐
FF2501_940228583 小时前
HarmonyOS应用《玄象》开发实战:罗盘手势缩放:PinchGesture + scale 属性的协同
harmonyos·鸿蒙
b130538100493 小时前
HarmonyOS应用《玄象》开发实战:命盘排布 Canvas:四柱干支 + 六十甲子纳音表的同步绘制
harmonyos·鸿蒙
木木子223 小时前
# 鸿蒙ArkTS实战:折扣计算器 — 快速百分比选择与省钱明细展示
华为·harmonyos
爱写代码的阿森3 小时前
鸿蒙三方库 | harmony-utils之ArrayUtil集合过滤排序与分块详解
华为·harmonyos·鸿蒙·huawei
不言鹅喻3 小时前
HarmonyOS ArkTS 实战:实现一个掷骰子模拟器
华为·harmonyos
LEO111105 小时前
HarmonyOS应用《玄象》开发实战:RenderingContextSettings(true) 抗锯齿对 Canvas 渲染的影响
harmonyos·鸿蒙
爱写代码的阿森5 小时前
鸿蒙三方库 | harmony-utils之ArrayUtil集合操作与去重详解
华为·harmonyos·鸿蒙·huawei
qizayaoshuap6 小时前
# 评分器组件开发实战:HarmonyOS ArkTS 五星评分交互应用解析
华为·交互·harmonyos
b130538100496 小时前
HarmonyOS应用《玄象》开发实战:AiPhotoFengshuiPage AI 拍照风水:@ohos.multimedia.camera 相机调用
harmonyos·鸿蒙