AI求职信生成:基于HarmonyOS与ArkTS的AI原生应用开发实践

摘要:本文以"AI求职信生成"应用为完整案例,系统阐述基于HarmonyOS Next操作系统与ArkTS语言开发AI原生应用的完整技术实践。文章严格遵循六阶段开发方法论——对齐、架构、原子化、审批、自动化执行、评估,从需求分析、架构设计、模块拆分、代码实现到质量控制,全方位呈现HarmonyOS生态下AI求职信生成应用开发的技术要点与最佳实践。全文包含核心代码片段、架构决策分析、ArkTS语法约束详解及性能优化策略,为HarmonyOS应用开发者提供可参考的完整技术方案。


在这里插入图片描述

一、对齐阶段(Align):从模糊需求到精确规范

1.1 项目上下文分析

"AI求职信生成"是运行在HarmonyOS Next系统上的AI原生应用,归属于一个包含多个 AI 应用的应用集合。该集合以"AI智能助手"为统一入口,覆盖健康生活、工作效率、创意娱乐、学习成长、职业发展六大领域,每个应用解决一个具体的用户场景问题。

1.1.1 技术栈全景

在开始编码之前,我们首先梳理了项目所涉及的技术栈,确保每个技术选型都经过充分考量:

技术维度 选型方案 版本/规格 选型理由
操作系统 HarmonyOS Next API 12+ 面向未来的全场景分布式OS
开发语言 ArkTS(基于TypeScript的鸿蒙原生语言) 原生支持,编译时类型安全
UI框架 ArkUI(声明式UI框架) 声明式范式,状态驱动渲染
路由方案 @kit.ArkUI router 系统内置 零额外依赖,原生性能
构建工具 Hvigor 官方构建工具,深度优化
包管理 oh-package.json5 标准鸿蒙包管理格式
1.1.2 现有代码模式分析

通过分析项目已有代码,我们识别出统一的架构模式——MVC变体(Model-View-Service),这是HarmonyOS社区中广泛采用的轻量级分层架构。每个应用由三个核心文件组成:

  1. *Page.ets:视图层,负责UI渲染和用户交互,以@Entry@Component装饰器标识。这是ArkUI声明式编程的核心载体,所有界面元素在此文件中定义。

  2. *Model.ets:数据模型层,定义数据结构,以export class导出。该层不包含任何业务逻辑,纯粹用于数据建模和类型约束。

  3. *Service.ets:业务逻辑层,封装数据生成和业务处理逻辑。该层是未来接入真实AI大模型API的扩展点。

这种模式在整个项目中被一致遵循,从"AI求职信生成"到"AI品牌起名Slogan"、"AI合同审查"等数十个应用,均采用相同的三文件结构。这种一致性极大地降低了维护成本和跨应用开发的认知负担。

Index.ets入口页面中,通过读取rawfile目录下的apps/apps.json配置文件动态加载应用列表,每个应用条目包含page字段指向对应的页面路径:

// Index.ets 中的动态加载逻辑
private loadApps(): void {
  try {
    let ctx: Context = getContext(this)
    let mgr = ctx.resourceManager
    let data: Uint8Array = mgr.getRawFileContentSync('apps/apps.json')
    let decoder: util.TextDecoder = util.TextDecoder.create('utf-8')
    let jsonStr: string = decoder.decodeToString(data)
    let rawList: AppJsonItem[] = JSON.parse(jsonStr) as AppJsonItem[]
    // ... 解析并构建AppInfo列表
  } catch {
    this.apps = this.getDefaultApps()
  }
}

这段代码展示了HarmonyOS资源管理的关键API:getRawFileContentSync用于读取rawfile目录下的二进制资源文件,TextDecoder用于将UTF-8编码的字节流解码为字符串。整个加载过程是同步的,适合在aboutToAppear生命周期钩子中执行。

1.1.3 应用启动流程分析

当用户从主页点击"AI求职信生成"卡片时,完整的调用链如下:

用户点击卡片 → router.pushUrl({ url: app.pageUrl })
  → 系统加载AI求职信生成Page.ets
    → @Entry装饰器触发页面初始化
      → @Component构建组件树
        → @State变量初始化
          → build()方法执行UI渲染
            → 用户看到输入表单

这个流程体现了HarmonyOS声明式UI的核心思想:开发者只需描述UI的状态和结构,框架负责渲染和更新。

1.2 需求理解与确认

1.2.1 原始需求分析

求职信生成是求职者职业发展中的关键环节。一份高质量的求职信需要精准匹配目标岗位、突出个人亮点、展现专业素养,同时还要符合目标公司的文化和行业惯例。AI求职信生成应用的需求可以拆解为以下功能点:

  • F1:收集用户输入的岗位信息(目标岗位、目标公司)
  • F2:收集用户的个人经历和技能摘要
  • F3:基于输入生成完整的求职信(Cover Letter)正文
  • F4:突出个人亮点,帮助用户在众多求职者中脱颖而出
  • F5:进行人岗匹配分析,展示求职者与岗位的契合度
  • F6:生成邮件主题建议,便于求职者通过邮件发送
  • F7:提供投递建议和面试准备提示
  • F8:生成多个版本的求职信,适配不同类型的公司(如初创公司 vs 大企业)
  • F9:识别目标公司类型,调整求职信的语气和重点
1.2.2 边界确认

经过需求澄清,我们确定了以下边界:

输入范围

  • 目标岗位(必填):用户填写的求职目标岗位,如"前端开发工程师"、"产品经理"等
  • 目标公司(必填):用户投递的目标公司名称
  • 个人经历(必填):用户的工作经历、项目经验、教育背景等

输出范围

  • cover_letter:完整的求职信正文
  • highlights:个人亮点列表(数组),3个突出的能力或成就
  • match_analysis:人岗匹配分析,说明求职者与岗位的匹配程度
  • subject:邮件主题建议,便于求职者通过邮件发送
  • tips:投递建议和面试准备提示
  • variants:多个版本的求职信(数组),适配不同类型公司
  • company_type:识别的公司类型(如"初创公司"、"大型企业"等)
  • adjusted:针对公司类型的求职信调整说明

非功能需求

  • 页面需在主流手机屏幕尺寸(360dp-428dp宽度)下正常显示
  • 交互响应时间不超过500ms(当前Mock数据阶段)
  • 支持深色模式(通过HarmonyOS的深色适配机制)

排除范围

  • 不涉及真实的AI大模型API调用(当前阶段使用Mock数据模拟)
  • 不涉及后端服务,所有逻辑在客户端本地执行
  • 不涉及用户认证和权限管理
  • 不涉及求职信的直接发送或投递功能
1.2.3 关键决策点

在需求分析过程中,我们识别出以下关键决策点并逐一解决:

决策1:数据模型字段设计

问题:求职信信息应该包含哪些字段?字段粒度如何界定?

方案评估:

  • 粗粒度:只包含"求职信正文"一个字段,简洁但信息量不足
  • 细粒度:拆分为正文、亮点、匹配分析、主题、建议、变体等多个字段,信息丰富

决策结果:采用细粒度设计。求职信生成不仅仅是写一段文字,还需要提供配套的投递建议、匹配分析等增值信息,这些信息对求职者来说具有很高的实用价值。

决策2:Mock数据策略

问题:是随机生成完全固定的数据,还是基于输入做简单的映射生成?

方案评估:

  • 固定数据:实现简单,但演示效果差,用户感觉不到输入与输出的关联
  • 基于输入的映射生成:需要写一些条件判断逻辑,但演示效果更真实

决策结果:采用基于输入的映射生成策略。例如,用户输入的岗位名称会被嵌入到求职信正文和匹配分析中,形成"生成结果:xxx岗位"的格式,让用户直观感受到输入的影响。

决策3:状态管理粒度

问题:@State变量应该设计为几个?

方案评估:

  • 单个状态对象:包含输入和输出,逻辑简单但任何字段变化都会触发整个UI重建
  • 分离输入和输出状态:输入变化不影响结果展示区,反之亦然,性能更好

决策结果:分离为三个状态变量——inputData用于输入收集,resultData用于结果存储,showResult用于控制显隐。

1.3 如何在没有真实AI API的情况下验证产品价值

这是一个非常实际的问题。在项目初期,我们往往无法立即获得AI大模型的API访问权限。我们的策略是:

  1. Mock数据模拟:使用模板字符串生成基于输入的演示数据,让用户看到输入与输出的关联性
  2. 数据结构预定义:按照真实API的返回格式设计数据模型,后续只需替换Service层的实现
  3. UI先行:先完成完整的UI交互流程,确保用户操作路径流畅

这种策略保证了产品价值的早期验证,同时为后续的AI能力接入预留了平滑的扩展路径。

1.4 达成共识

对齐阶段最终产出了明确的需求规范文档:

  • 验收标准:用户输入岗位、公司、个人经历后,点击"寄出信件"按钮,页面展示完整的求职信结果,包含cover_letter、highlights、match_analysis等9个字段的全部展示
  • 技术约束:必须遵循ArkTS语法约束(不支持any/unknown类型、不支持解构赋值、不支持索引签名、不支持函数表达式等)
  • 集成方案:作为独立页面,通过router.pushUrl从主页导航进入,通过router.back()返回
  • 数据流规范:单向数据流,用户输入 → Service处理 → State更新 → UI渲染

二、架构阶段(Architect):从系统设计到模块规范

2.1 整体架构设计

基于对齐阶段的共识,我们设计了"AI求职信生成"的软件架构。整个架构遵循HarmonyOS的声明式开发范式,采用经典的三层架构。

2.1.1 架构分层图
┌──────────────────────────────────────────────────────────┐
│                      视图层(View)                        │
│               AI求职信生成Page.ets                         │
│  @Entry @Component 声明式UI + @State 状态管理 + 条件渲染  │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  信封Header(返回按钮 + 标题 + 装饰图标)            │ │
│  │  信纸输入表单(岗位 + 公司 + 个人经历)              │ │
│  │  寄出信件按钮(触发数据生成)                        │ │
│  │  回信结果卡片(9个字段的条件渲染展示)                │ │
│  └──────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────┤
│                    业务逻辑层(Service)                    │
│               AI求职信生成Service.ets                      │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  generateData(input): AI求职信生成Data                │ │
│  │  - 输入参数校验和类型转换                            │ │
│  │  - Mock数据生成(基于输入映射)                      │ │
│  │  - 结果对象组装和返回                                │ │
│  └──────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────┤
│                    数据模型层(Model)                      │
│               AI求职信生成Model.ets                        │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  class AI求职信生成Data {                            │ │
│  │    cover_letter: string     // 求职信正文            │ │
│  │    highlights: string[]     // 个人亮点列表          │ │
│  │    match_analysis: string   // 人岗匹配分析          │ │
│  │    subject: string          // 邮件主题建议          │ │
│  │    tips: string             // 投递建议              │ │
│  │    variants: string[]       // 求职信变体列表        │ │
│  │    company_type: string     // 公司类型              │ │
│  │    adjusted: string         // 调整说明              │ │
│  │  }                                                   │ │
│  └──────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────┤
│                  系统层(HarmonyOS SDK)                   │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  @kit.ArkUI(router)│ ArkTS运行时 │ 资源管理         │ │
│  └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
2.1.2 模块依赖关系与接口契约
AI求职信生成Page.ets
    ├── import { AI求职信生成Data } from './AI求职信生成Model'
    ├── import { AI求职信生成Service } from './AI求职信生成Service'
    └── import { router } from '@kit.ArkUI'

三个模块的依赖关系是单向的:Page → Service → Model,不存在循环依赖,符合高内聚低耦合的设计原则。这种设计带来的好处是:

  • 可测试性:Service层可以脱离UI层独立测试
  • 可替换性:替换Mock数据为真实API时,只需修改Service层
  • 可维护性:每个模块职责清晰,修改范围可控

2.2 数据流向设计

数据在应用中的流转遵循"单向数据流"原则,这是ArkUI声明式框架的核心设计理念。与传统的双向绑定不同,单向数据流使得数据变化可预测、可追踪:

用户输入(TextInput onChange 回调)
    │
    ▼ 写入状态
@State inputData: Record<string, Object> = {}
    │
    ▼ 按钮点击事件
this.service.generateData(this.inputData)
    │
    ▼ 返回新数据
@State resultData: AI求职信生成Data | null = null
    │
    ▼ 状态变更触发UI自动重新渲染
UI自动重新渲染(声明式绑定)
    │
    ▼
用户查看求职信结果

这种数据流设计的关键优势在于:

  1. 可预测性:数据变化的方向是确定的,不存在双向绑定可能导致的循环更新问题
  2. 调试友好:可以在状态变化的每个环节添加日志输出,追踪数据流转
  3. 性能优化:框架可以精确知道哪些组件需要更新,避免不必要的渲染

2.3 数据模型设计

AI求职信生成Data类的设计考虑了求职信的完整信息维度,共包含8个字段,覆盖了求职信的核心要素:

// 文件:entry/src/main/ets/apps/AI求职信生成/AI求职信生成Model.ets

export class AI求职信生成Data {
  // 求职信核心内容(2个字段)
  cover_letter: string = ''       // 求职信正文,完整的求职信文本
  highlights: string[] = []       // 个人亮点列表(数组),突出3个核心能力

  // 分析与建议(3个字段)
  match_analysis: string = ''     // 人岗匹配分析,展示求职者与岗位的契合度
  subject: string = ''            // 邮件主题建议,便于求职者通过邮件发送
  tips: string = ''               // 投递建议,面试准备提示

  // 版本与适配(3个字段)
  variants: string[] = []         // 求职信变体列表(数组),适配不同类型公司
  company_type: string = ''       // 公司类型,如"初创公司"、"大型企业"等
  adjusted: string = ''           // 调整说明,针对公司类型的求职信调整描述

  constructor() {
    // 显式初始化所有字段(ArkTS要求)
    this.cover_letter = ''
    this.highlights = []
    this.match_analysis = ''
    this.subject = ''
    this.tips = ''
    this.variants = []
    this.company_type = ''
    this.adjusted = ''
  }
}
设计决策深度解析

1. 为什么字段名使用英文?

求职信生成的应用场景天然涉及中英文混合内容(如岗位名称、公司名称可能是英文的),字段名使用英文可以避免编码问题和潜在的跨语言兼容性问题。同时,英文字段名在序列化为JSON时也更加通用。

2. 数据类型选择

highlightsvariants字段使用string[]数组类型。在UI层,通过ForEach组件遍历数组:

if (this.resultData.highlights) {
  ForEach(this.resultData.highlights, (item: string, index: number) => {
    Row() {
      Text('• ').fontSize(12).fontColor('#666666')
      Text(item).fontSize(12).fontColor('#333333')
    }
    .width('100%').padding({ top: 2, bottom: 2 })
  }, (item: string, index: number) => index.toString())
}

3. 构造函数中的字段初始化

ArkTS要求在类声明体内声明字段,并在构造函数中显式初始化。不能在构造函数参数中声明字段:

// ❌ ArkTS不支持
class Foo {
  constructor(public name: string) {}
}

// ✅ ArkTS支持的写法
class Foo {
  name: string = ''
  constructor() {
    this.name = ''
  }
}

2.4 服务层设计

服务层封装了核心业务逻辑,是应用的可扩展核心。当前阶段使用Mock数据,未来替换为真实AI API调用时,只需修改此层的实现:

// 文件:entry/src/main/ets/apps/AI求职信生成/AI求职信生成Service.ets

import { AI求职信生成Data } from './AI求职信生成Model'

export class AI求职信生成Service {
  private model: AI求职信生成Data

  constructor() {
    this.model = new AI求职信生成Data()
  }

  // 生成AI求职信生成数据
  generateData(input: Record<string, Object>): AI求职信生成Data {
    let result: AI求职信生成Data = new AI求职信生成Data()
    // Mock data generation based on input
    let positionVal: string = String(input['position'] || '')

    result.cover_letter = '生成结果:' + positionVal
    result.highlights = ['示例项1', '示例项2', '示例项3']
    result.match_analysis = '生成结果:' + positionVal
    result.subject = '生成结果:' + positionVal
    result.tips = '生成结果:' + positionVal
    result.variants = ['示例数据1', '示例数据2', '示例数据3']
    return result
  }
}
关键设计点

1. 输入参数类型:Record<string, Object>

这个类型选择是经过深思熟虑的。Record<K, V>是ArkTS支持的少数TypeScript实用类型之一(与Partial、Required、Readonly并列)。它表示一个键为string、值为Object的映射类型。相比any,它提供了基本的类型约束;相比具体的接口类型,它又保持了灵活性,允许动态添加字段。

2. 显式类型转换

String(input['position'] || '')这行代码展示了ArkTS中推荐的类型安全实践:

  • 使用|| ''提供默认值,防止undefined
  • 使用String()函数显式转换,确保类型安全
  • 避免使用隐式转换(如input['position'] + ''

3. Mock数据与真实API的替换策略

当前Service层返回的是硬编码的Mock数据。未来替换为真实AI API时,只需修改generateData方法的实现:

// 未来接入真实API的示意代码
async generateData(input: Record<string, Object>): Promise<AI求职信生成Data> {
  let response = await http.request({
    url: 'https://api.example.com/cover-letter/generate',
    method: http.RequestMethod.POST,
    data: JSON.stringify(input)
  })
  return this.parseResponse(response)
}

这种替换对Page层完全透明,Page层不需要做任何修改。

2.5 视图层设计

视图层是ArkTS声明式UI的核心体现,采用@Component装饰器定义组件:

// 文件:entry/src/main/ets/apps/AI求职信生成/AI求职信生成Page.ets

import { AI求职信生成Data } from './AI求职信生成Model'
import { AI求职信生成Service } from './AI求职信生成Service'
import { router } from '@kit.ArkUI'

@Entry
@Component
struct AI求职信生成Page {
  @State inputData: Record<string, Object> = {}
  @State resultData: AI求职信生成Data | null = null
  @State showResult: boolean = false
  private service: AI求职信生成Service = new AI求职信生成Service()

  build() {
    Column() {
      // 1. 信封Header
      this.buildHeader()
      // 2. 可滚动内容区域
      Scroll() {
        Column() {
          // 2.1 信纸输入表单
          this.buildInputForm()
          // 2.2 寄出信件按钮
          this.buildSubmitButton()
          // 2.3 回信结果展示(条件渲染)
          if (this.showResult && this.resultData !== null) {
            this.buildResultCard()
          }
        }
      }
    }
  }
}
状态管理设计

三个@State变量的设计遵循了"最小状态原则":

状态变量 类型 用途 触发更新条件
inputData Record<string, Object> 存储用户输入的三个字段 每次输入变化
resultData AI求职信生成Data | null 存储生成结果 点击生成按钮
showResult boolean 控制结果区域的显隐 点击生成按钮/返回

为什么resultData使用联合类型而不是空对象?

使用AI求职信生成Data | null而非AI求职信生成Data(初始化为空对象),是因为:

  • null明确表示"尚未生成数据"的状态
  • 在条件渲染中,可以通过!== null进行类型收窄(type narrowing)
  • 避免将"空数据"和"尚未生成"两种状态混淆

三、原子化阶段(Atomize):任务分解与模块实现

3.1 任务分解与依赖管理

将"AI求职信生成"应用开发任务分解为以下原子任务,每个任务都有明确的输入、输出和验收标准:

任务ID 任务名称 预估工时 前置依赖 验收标准
T1 数据模型类定义(Model) 0.5h 类定义完整,8个字段均已声明和初始化
T2 服务层业务逻辑(Service) 1h T1 generateData方法可返回完整数据对象
T3 页面布局与UI组件 2h 信封Header、信纸输入表单、按钮布局完成
T4 用户输入处理逻辑 0.5h T3 输入变化能正确写入inputData
T5 数据生成与结果展示 1h T2, T3, T4 点击按钮后展示完整求职信结果
T6 路由配置与导航 0.5h T3 点击返回可回到主页
T7 样式与视觉优化 0.5h T5 字体、颜色、间距符合设计规范
T8 测试与调试 1h T1-T7 所有功能正常,无编译错误

任务之间的依赖关系图如下:

T1 (Model) → T2 (Service) → T5 (结果展示)
                                ↑
T3 (布局) → T4 (输入处理) → T5 (结果展示)
T3 (布局) → T6 (路由)
T5 → T7 (样式优化)
T1-T7 → T8 (测试)

3.2 核心实现详解

3.2.1 页面顶部信封Header(T3)

顶部信封Header是整个页面的"门面",包含三个部分:返回按钮、标题区域和装饰图标。采用Row水平布局实现左右分布:

Row() {
  // 左侧:返回按钮
  Text('← 返回')
    .fontSize(13)
    .fontColor('#5C4033')
    .onClick(() => { router.back() })

  Blank()  // 弹性间距

  // 中间:标题和副标题
  Column() {
    Text('📱 AI求职信生成')
      .fontSize(18)
      .fontWeight(FontWeight.Bold)
      .fontColor('#2C1810')
    Text('✉ 信件')
      .fontSize(10)
      .fontColor('#8B6914')
      .margin({ top: 2 })
  }

  Blank()  // 弹性间距

  // 右侧:装饰图标
  Text('✉').fontSize(22)
}
.width('100%')
.padding({ left: 20, right: 20, top: 16, bottom: 14 })
.backgroundColor('#F5F0E0')

设计要点

  1. 主题色设计:整个页面采用暖色调——米黄色(#F5F0E0)背景搭配深棕色(#2C1810)文字,营造出复古信纸的温暖质感。这种色彩设计不仅视觉上舒适,还通过"信纸"的隐喻强化了"求职信"的产品定位。

  2. Blank()组件实现弹性布局Blank()是ArkUI中的弹性空白组件,它会占据剩余空间。在Row中放置两个Blank(),分别位于标题的左右两侧,实现了标题居中的效果,等价于Flex布局的space-between

  3. 视觉层次感:主标题使用18号字体加粗,副标题使用10号字体金色,形成了清晰的视觉层次。这种设计引导用户先关注主标题,再阅读副标题。

3.2.2 用户输入表单(T4)

输入表单包含三个输入字段,每个字段遵循相同的设计模式——标签 + 输入框的组合。特别地,整个表单被设计在"信纸"卡片中,强化了"写求职信"的沉浸感:

Column() {
  // 岗位输入
  Text('岗位')
    .fontSize(11)
    .fontColor('#5C4033')
    .margin({ top: 6, bottom: 3 })
  TextInput({ placeholder: '请输入岗位' })
    .fontSize(13)
    .height(40)
    .backgroundColor('transparent')
    .border({ width: { bottom: 1 }, color: '#B8A88A' })
    .padding({ left: 8, right: 8 })
    .onChange((val: string) => { this.inputData['岗位'] = val })

  // 公司输入
  Text('公司')
    .fontSize(11)
    .fontColor('#5C4033')
    .margin({ top: 6, bottom: 3 })
  TextInput({ placeholder: '请输入公司' })
    .fontSize(13)
    .height(40)
    .backgroundColor('transparent')
    .border({ width: { bottom: 1 }, color: '#B8A88A' })
    .padding({ left: 8, right: 8 })
    .onChange((val: string) => { this.inputData['公司'] = val })

  // 个人经历输入
  Text('个人经历')
    .fontSize(11)
    .fontColor('#5C4033')
    .margin({ top: 6, bottom: 3 })
  TextInput({ placeholder: '请输入个人经历' })
    .fontSize(13)
    .height(40)
    .backgroundColor('transparent')
    .border({ width: { bottom: 1 }, color: '#B8A88A' })
    .padding({ left: 8, right: 8 })
    .onChange((val: string) => { this.inputData['个人经历'] = val })
}
.width('100%')
.padding({ left: 24, right: 24, top: 20, bottom: 20 })
.backgroundColor('#FFFDF5')
.margin({ top: 12 })
.border({ width: 1, color: '#D4C5A9' })

关键ArkTS语法要点详解

1. Record类型与索引访问

this.inputData['岗位'] = val 这种写法在ArkTS中是允许的,因为inputData的类型是Record<string, Object>,而Record是ArkTS明确支持的少数TypeScript实用类型之一。但需要注意,普通对象的索引签名(如interface Foo { [key: string]: string })在ArkTS中是不支持的。

// ❌ ArkTS不支持索引签名
interface Foo {
  [key: string]: string  // 编译错误
}

// ✅ ArkTS支持Record工具类型
let data: Record<string, string> = {}
data['key'] = 'value'  // 允许

2. TextInput的onChange回调

onChange((val: string) => { ... })中的回调必须是箭头函数,因为ArkTS不支持函数表达式。箭头函数自动捕获外层的this上下文,使得在回调中可以访问组件的@State变量。

3. 信纸风格装饰

输入框使用了border({ width: { bottom: 1 }, color: '#B8A88A' }),只显示底部边框,模拟了信纸上的横线效果。这种设计细节虽小,但显著提升了产品的整体质感和用户体验。

4. 透明背景

backgroundColor('transparent')让输入框融入信纸背景,进一步强化了"信纸"的视觉隐喻。用户感觉自己是在一张信纸上填写内容,而非在一个普通的APP表单中操作。

3.2.3 寄出信件按钮(T5)

"寄出信件"按钮是整个应用的核心交互入口,它的设计直接影响用户体验:

Button('📱  寄出信件')
  .width('100%')
  .height(50)
  .backgroundColor('#8B4513')
  .borderRadius(6)
  .fontColor('#F5F0E0')
  .fontSize(16)
  .fontWeight(FontWeight.Bold)
  .margin({ top: 18, bottom: 14 })
  .onClick(() => {
    this.resultData = this.service.generateData(this.inputData)
    this.showResult = true
  })

交互逻辑分析

点击按钮时,以下事件顺序发生:

  1. 调用this.service.generateData(this.inputData)生成求职信数据
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐