在这里插入图片描述

鸿蒙 ArkUI 分页账单明细表:从零到一构建企业级财务数据展示组件

一、项目概述

1.1 背景与意义

在移动端财务管理、企业后台、电商订单管理等场景中,数据表格是最基础也是最重要的信息载体之一。当数据量级从几十条增长到数千甚至数万条时,如何高效、流畅地展示数据,同时保持良好的用户体验,成为前端开发者必须面对的核心挑战。

本项目基于 HarmonyOS ArkUI(ArkTS 语言)实现了一个分页账单明细表组件,旨在解决大账单数据的分页展示问题。项目运行于 API 24(HarmonyOS 6.1.1)平台,采用 Stage 模型架构,严格遵循 ArkTS 的类型安全规范。

1.2 技术栈

技术 版本 说明
HarmonyOS 6.1.1 (API 24) 目标操作系统
ArkTS 3.0+ 声明式 UI 开发语言
ArkUI API 24 组件库与布局引擎
Stage 模型 应用架构模型
DevEco Studio 6.26.1 IDE 开发工具
Hvigor 6.26.1 构建工具

1.3 核心功能清单

  • 分页展示:87 条模拟账单数据,每页 10 条,共 9 页
  • 分页控件:上一页 / 页码按钮组(含智能省略号)/ 下一页
  • 表格渲染:表头固定 + 数据行可滚动 + 交替行背景色
  • 统计摘要:顶部显示总记录数、当前数据范围
  • 金额着色:收入绿色(+)、支出红色(-)
  • 状态着色:已完成(绿)、处理中(橙)、已退款(红)
  • 数据统计卡片:总记录数、总收入、总支出
  • 零第三方依赖:纯 ArkUI 原生实现

二、项目结构设计

2.1 目录组织

entry/src/main/ets/
├── model/
│   └── BillItem.ets              # 数据模型层
├── components/
│   └── PaginatedBillTable.ets    # UI 组件层(核心)
└── pages/
    └── Index.ets                 # 页面入口 + 模拟数据

项目的架构清晰地划分为三层:

  1. Model 层BillItem.ets):定义账单数据的实体结构,包含字段、类型和构造函数。
  2. Component 层PaginatedBillTable.ets):封装表格展示和分页逻辑,是一个可复用的 @Component,通过 @Prop 接收外部数据,通过 @State 维护内部分页状态。
  3. Page 层Index.ets):作为应用的入口页面,负责生成模拟数据、布局标题栏和统计卡片,并组合使用 PaginatedBillTable 组件。

这种分层设计的好处是:职责单一、高内聚低耦合。如果未来需要将分页表格复用到其他页面(如订单页、流水页),只需导入 PaginatedBillTable 组件即可。

2.2 组件树

Index (Page)
├── TitleBar (Row + Text)
├── SummaryCards (Row)
│   ├── SummaryCard (总记录数)
│   ├── SummaryCard (总收入)
│   └── SummaryCard (总支出)
└── PaginatedBillTable (Component)
    ├── StatsRow (统计信息栏)
    ├── TableArea (表格区域)
    │   ├── HeaderRow (表头:6列)
    │   ├── Scroll (可滚动区域)
    │   │   ├── BillRow × N (数据行)
    │   │   └── ...
    │   └── ──
    └── PaginationBar (分页控件)
        ├── PrevButton (上一页)
        ├── PageButtons (页码按钮组)
        └── NextButton (下一页)

三、数据模型深度解析

3.1 BillItem 实体

export class BillItem {
  id: string;          // 交易编号,如 "B2026001"
  date: string;        // 交易日期,如 "2026-01-01"
  description: string; // 交易描述,如 "公司食堂午餐"
  category: string;    // 交易分类,如 "餐饮"
  amount: number;      // 交易金额,如 35.50
  isIncome: boolean;   // 是否为收入
  status: string;      // 交易状态,如 "已完成"
}

设计这个模型时遵循了以下原则:

  • 语义明确:每个字段名都直观表达其含义,isIncome 用布尔值而非字符串来区分收支,避免了 “income”/“expense” 字符串比较带来的性能损耗和拼写错误风险。
  • 类型安全:所有字段都显式标注类型,充分利用 ArkTS 的静态类型检查。
  • 金额处理amount 使用 number 类型,在显示时通过 toFixed(2) 格式化为两位小数,避免浮点数精度问题暴露给用户。
  • 日期处理date 使用字符串类型而非 Date 对象,简化序列化和比较操作,显示时直接渲染。

3.2 参数接口设计

对于 ArkTS 中 @Builder 方法的参数传递,本项目定义了两个命名接口:

BillRowParams(组件内部使用):

export interface BillRowParams {
  item: BillItem;
  rowIndex: number;
}

SummaryCardParams(页面级使用):

interface SummaryCardParams {
  label: string;
  value: string;
  unit: string;
  color: string;
}

为什么需要接口而非内联类型?在 ArkTS 的严格模式(arkts-no-obj-literals-as-types 规则)下,@Builder 方法的参数类型必须是一个命名的 interfaceclass,不能是内联对象类型如 { label: string; value: string }。这一设计强制开发者以显式类型契约的方式传递参数,提升了代码的可读性和可维护性。


四、分页表格组件核心实现

4.1 组件声明与属性

@Component
export struct PaginatedBillTable {
  @Prop data: BillItem[] = [];
  @Prop pageSize: number = 10;
  @State currentPage: number = 1;
  // ...
}
  • @Prop data:父组件传入的账单数据数组。使用 @Prop 而非 @State 表明数据所有权属于父组件,子组件只读展示。
  • @Prop pageSize:每页显示的记录数,默认 10 条,父组件可按需调整。
  • @State currentPage:当前页码,从 1 开始。使用 @State 表明这是组件内部状态,当页码变化时,ArkUI 会自动触发 UI 重新渲染。

4.2 计算属性(Getter)

组件中定义了一系列计算属性,用于派生展示所需的数据:

get totalPages(): number {
  return Math.ceil(this.data.length / this.pageSize);
}

get currentPageData(): BillItem[] {
  const start = (this.currentPage - 1) * this.pageSize;
  const end = Math.min(start + this.pageSize, this.data.length);
  return this.data.slice(start, end);
}

get rangeStart(): number {
  return (this.currentPage - 1) * this.pageSize + 1;
}

get rangeEnd(): number {
  return Math.min(this.currentPage * this.pageSize, this.data.length);
}

这些计算属性的设计体现了 “数据驱动视图” 的思想:currentPage 是状态,所有展示数据都是由 currentPagedata 派生而来。当用户点击页码按钮改变 currentPage 时,currentPageDatarangeStartrangeEnd 会自动重新计算,驱动表格内容更新。

4.3 分页页码生成算法

getPageNumbers(): number[] {
  const total = this.totalPages;
  const current = this.currentPage;
  const pages: number[] = [];
  
  if (total <= 7) {
    for (let i = 1; i <= total; i++) pages.push(i);
  } else {
    pages.push(1);  // 始终显示第一页
    
    if (current > 3) pages.push(-1); // 左侧省略号
    
    // 当前页 + 前后各一页
    const start = Math.max(2, current - 1);
    const end = Math.min(total - 1, current + 1);
    for (let i = start; i <= end; i++) pages.push(i);
    
    if (current < total - 2) pages.push(-1); // 右侧省略号
    
    pages.push(total); // 始终显示最后一页
  }
  return pages;
}

这个算法的设计要点:

  • 当总页数 ≤ 7 时:显示全部页码,因为按钮数量在可接受范围内。
  • 当总页数 > 7 时:采用"首尾固定 + 中间折叠"策略:
    • 始终显示第 1 页和最后 1 页
    • 始终显示当前页及其前后各 1 页
    • -1 作为省略号占位符,在渲染时判断 page === -1 则渲染 ...

这种策略保证了无论数据有多少页,页码按钮组最多只显示 7 个按钮(首 + 尾 + 省略号 ×2 + 当前页周边 ×3),在可用性和空间占用之间取得了良好平衡。

4.4 表格行渲染与交替背景色

@Builder
BillRow(params: BillRowParams) {
  Row() {
    // ... 各列 Text 组件
  }
  .backgroundColor(params.rowIndex % 2 === 0 ? '#FAFAFA' : '#FFFFFF')
  .border({ width: { bottom: 1 }, color: { bottom: '#F0F0F0' } })
}
  • 斑马纹效果:通过 rowIndex % 2 === 0 判断奇偶行,偶数列(#FAFAFA浅灰)和奇数列(#FFFFFF纯白)交替,提升长表格的可读性。
  • 下边框:使用 border({ width: { bottom: 1 }, color: { bottom: '...' } })EdgeWidths 语法,仅设置底部边框,形成表格线的视觉效果。

4.5 Scroll 可滚动区域

Scroll() → Column() → ForEach → BillRow × N

数据行区域包裹在 Scroll 容器中,当当前页数据行数较多超出可视区域时,用户可以通过滚动查看所有行。Scroll 组件通过 layoutWeight(1) 占据剩余空间,并使用 scrollBar(BarState.Auto) 自动显示/隐藏滚动条。

这里有一个值得注意的设计选择:为什么不在整个表格上滚动,而只让数据行区域滚动?因为表头需要固定不动,确保用户在滚动查看数据时始终能看到列名,这是优秀表格设计的通行做法。


五、分页控件深度剖析

5.1 控件结构

分页控件位于表格底部,其结构为:

Row (FlexAlign.Center)
├── Button "‹ 上一页"     ← margin({ right: 8 })
├── Row (灵活宽度)
│   ├── Text "1" / Button "1"  ← margin({ left: 3, right: 3 })
│   ├── Text "..."             ← margin({ left: 3, right: 3 })
│   ├── Button "3" (高亮)      ← margin({ left: 3, right: 3 })
│   └── ...
└── Button "下一页 ›"     ← margin({ left: 8 })

5.2 控件状态管理

  • 禁用状态:当前页为第 1 页时,「上一页」按钮的 enabled 属性为 false;当前页为最后一页时,「下一页」按钮的 enabled 属性为 false。同时通过 fontColor 控制文字颜色变淡(#CCCCCC),给用户清晰的可交互暗示。
  • 高亮状态:当前页码按钮使用白色文字 + 深蓝背景(#1A3A5C),且边框宽度为 0,其他页码按钮使用深色文字 + 白色背景 + 1px 灰色边框。两者形成鲜明的视觉对比。

5.3 交互事件

// 上一页
.prevPage()this.currentPage - 1

// 指定页码
.goToPage(page) → 边界检查后赋值 this.currentPage = page

// 下一页
.nextPage()this.currentPage + 1

所有分页操作最终都归结为修改 @State currentPage。ArkUI 的响应式系统会:

  1. 检测到 currentPage 变化
  2. 重新计算所有依赖 currentPage 的 Getter(currentPageDatarangeStartrangeEnd 等)
  3. 驱动 UI 重新渲染(ForEach 刷新数据行、页码按钮高亮切换、按钮禁用状态更新)

这一过程无需开发者手动操作 DOM 或维护额外状态,充分体现了声明式 UI 框架的优势。


六、页面集成与模拟数据

6.1 Index 页面布局

@Entry
@Component
struct Index {
  @State bills: BillItem[] = mockBillsData();
  pageSize: number = 10;
  
  build() {
    Column() {
      TitleBar         // 顶部标题栏
      SummaryCardsRow  // 统计卡片行
      PaginatedBillTable // 分页表格(占据剩余空间)
    }
  }
}

页面采用纵向 Column 布局,从上到下依次排列标题栏、统计卡片和分页表格。PaginatedBillTable 通过 layoutWeight(1) 占据除标题栏和统计卡片外的所有剩余空间。

6.2 统计卡片

@Builder
SummaryCard(params: SummaryCardParams) {
  Column() {
    Text(params.label)     // "总记录数"
    Row() {
      Text(params.value)   // "87"
      Text(params.unit)    // "条"
    }
  }
}

三张统计卡片(总记录数、总收入、总支出)并排显示在标题栏下方,收入使用绿色(#1B8A3D)标记,支出使用红色(#C4353D)标记,颜色值与表格中的金额着色保持一致,形成统一的视觉语言。

calcTotalIncome(): number {
  let total = 0;
  for (let i = 0; i < this.bills.length; i++) {
    if (this.bills[i].isIncome) total += this.bills[i].amount;
  }
  return total;
}

6.3 模拟数据生成策略

mockBillsData() 函数生成 87 条结构完整、内容多样的模拟记录:

  • 日期分布:以 2026-01-01 为基准,每 3 条记录递增一天,覆盖 29 天的时间跨度
  • 描述多样性:30 种真实的交易描述(“公司食堂午餐”“京东购物”"工资发放"等),循环使用
  • 分类覆盖:10 种常见消费类别(餐饮/交通/购物/工资/转账/红包/生活缴费/娱乐/医疗/其他)
  • 收支比例:每 4 条中约有 1 条为收入(工资/奖金/红包),模拟真实账单的收支分布
  • 金额范围:收入 2000~20000 元,支出 5~500 元,贴合真实场景
  • 状态分布:90% 已完成、少量处理中和已退款
const isIncome = (i % 4 === 0);
const amount = isIncome
  ? Math.round((2000 + Math.random() * 18000) * 100) / 100
  : Math.round((5 + Math.random() * 500) * 100) / 100;

七、视觉设计理念

7.1 配色方案

用途 色值 说明
标题栏背景 #0D2137 深海军蓝,传递专业感
表头背景 #1A3A5C 中深蓝,与标题栏形成层次
页面背景 #F0F2F5 浅灰,减少视觉疲劳
收入金额 #1B8A3D (Green) 绿色代表正向收益
支出金额 #C4353D (Red) 红色代表支出消耗
已完成 Color.Green 绿色状态标识
处理中 Color.Orange 橙色表示进行中
已退款 Color.Red 红色表示逆向交易
当前页码 #1A3A5C 背景 + 白色文字 高亮当前页
其他页码 白色背景 + #333 文字 默认状态

配色整体采用 “深蓝 + 白” 的主色调,搭配 绿/红 作为数据语义色,风格偏向专业财务软件,适合企业级应用场景。

7.2 阴影与圆角

  • 表格区域shadow({ radius: 6, color: '#20000000' }) 轻微阴影提升层次感
  • 统计卡片shadow({ radius: 4, color: '#15000000' }) 更柔和的阴影
  • 表头borderRadius({ topLeft: 6, topRight: 6 }) 圆角与表格整体 borderRadius(6) + clip(true) 配合,实现优雅的圆角边框效果
  • 按钮:统一使用 borderRadius(6) 圆角按钮,保持视觉一致性

7.3 交互反馈

  • 页码按钮:悬浮时无状态变化(Native 端默认),但点击时通过 onClick 立即切换 currentPage,UI 即时响应
  • 禁用按钮:颜色变淡(#CCCCCC)且 enabled 为 false,阻止点击事件并给予视觉暗示
  • 文字溢出:交易描述列设置 maxLines(1) + textOverflow({ overflow: TextOverflow.Ellipsis }),超长文本以省略号截断,保证表格布局稳定

八、ArkTS 开发注意事项与踩坑记录

8.1 对象字面量规则(arkts-no-untyped-obj-literals)

ArkTS 编译器要求所有对象字面量必须对应一个已声明的类或接口。这意味着:

// ❌ 错误:内联对象类型
@Builder BillRow(params: { item: BillItem; rowIndex: number }) { }

// ❌ 错误:无类型匹配的对象字面量
this.BillRow({ item: item, rowIndex: index })

// ✅ 正确:预定义接口
export interface BillRowParams {
  item: BillItem;
  rowIndex: number;
}

// ✅ 正确:显式类型断言
this.BillRow({ item: item, rowIndex: index } as BillRowParams)

这一规则在最初开发时导致编译失败,错误信息为 arkts-no-obj-literals-as-typesarkts-no-untyped-obj-literals。解决方案是:始终为 @Builder 的参数定义命名接口,并在调用处使用 as Type 显式断言

8.2 Border 的 EdgeWidths 语法

ArkUI 的 border() 方法接受 BorderOptions 对象,其 widthcolor 属性支持 EdgeWidths / EdgeColors 子对象语法:

// 完整边框
.border({ width: 1, color: '#E0E0E0', style: BorderStyle.Solid })

// 仅底部边框
.border({ width: { bottom: 1 }, color: { bottom: '#F0F0F0' } })

初次实现时尝试使用 .border({ bottom: { width: 1, color: '...' } }) 的方式,但这不符合 BorderOptions 类型定义(它没有 bottom 顶级字段),导致编译错误。正确用法是将 bottom 放在 widthcolor 的子对象中。

8.3 Row 的 spacing 属性

在当前的 API 版本中,Row 组件不支持 .space() 方法。如果需要控制子元素间距,有两种替代方案:

  1. 使用 Space()Blank() 占位组件(适合少量、固定的间距场景)
  2. 使用子元素的 .margin() 属性(适合灵活、可变的间距场景)

本项目采用方案二,通过 .margin({ left: 3, right: 3 }) 为每个页码按钮添加间距,通过 .margin({ right: 8 }).margin({ left: 8 }) 控制上一页/下一页按钮两侧的间距。

8.4 readonly 在 struct 中不可用

在 ArkTS 的 @Component struct 中,readonly 关键字不被支持。如果确实需要不可变属性,有两种方案:

  1. 不使用 readonly,靠代码约定保证不修改
  2. 将常量定义在 struct 外部(如文件级常量)
// ❌ 错误
struct Index {
  readonly pageSize: number = 10;
}

// ✅ 正确
struct Index {
  pageSize: number = 10;
}

8.5 函数声明顺序

在 ArkTS 中,如果一个函数在 struct 的初始化器中被调用(如 @State bills: BillItem[] = mockBillsData()),该函数必须在 struct 定义之前声明。虽然在某些 JavaScript/TypeScript 环境中函数声明会被提升(hoisting),但在 ArkTS 的编译上下文中,将函数定义放在使用位置之前是最稳妥的做法。

// ✅ 正确:函数先定义
function mockBillsData(): BillItem[] { ... }

@Entry
@Component
struct Index {
  @State bills: BillItem[] = mockBillsData();
}

8.6 switch 语句的局限性

在 ArkTS 中,某些场景下的 switch 语句可能需要改写为 if/else if 链。虽然 ArkTS 不完全禁用 switch,但为了更好的兼容性和代码可读性,本项目统一使用 if/else if 来实现多分支逻辑。

// 推荐:使用 if/else if 替代 switch
getStatusColor(status: string): Color {
  if (status === '已完成') return Color.Green;
  if (status === '处理中') return Color.Orange;
  if (status === '已退款') return Color.Red;
  return Color.Gray;
}

九、性能考量与优化

9.1 数据切片 vs 一次性渲染

本项目采用前端数据切片策略:所有 87 条数据一次性传入组件,组件内部通过 Array.slice() 按当前页截取展示。这种策略适用于千条级以下的数据规模,优点是实现简单、无网络延迟。

对于万条级以上数据,建议改为服务端分页模式:组件仅维护当前页数据,通过回调通知父组件或接口层加载新数据。

9.2 ForEach 的键值优化

ForEach(this.currentPageData, 
  (item, index) => { this.BillRow(...) },
  (item) => item.id   // 唯一且稳定的键
)

ForEach 的第三个参数是键值生成函数,用于标识列表中每个项目的唯一性。使用 item.id 作为键值:

  • 唯一性:每笔交易的 ID 都不同
  • 稳定性:ID 在数据生命周期内不变
  • 高效:字符串比较性能优异

正确的键值可以帮助 ArkUI 的 diff 算法在数据变化时最小化 DOM 操作,提升列表更新性能。

9.3 Scroll + layoutWeight 的布局优化

Column (布局容器)
├── Scroll
│   └── Column (数据行)
└── PaginationBar (分页控件)

Scroll 通过 layoutWeight(1) 占据 Column 中的剩余空间,PaginationBar(分页控件)的尺寸由内容决定(高度固定 50px)。这种布局确保:

  • 分页控件始终位于表格底部,不会被挤出屏幕
  • 数据行区域随可用空间自动伸缩
  • 数据行过多时可滚动查看

9.4 条件渲染

PaginationBarForEach 中,通过 if (page === -1) 判断渲染省略号文本还是页码按钮。ArkUI 的编译器会将 if/else 转换为 If 组件,实现条件渲染:

ForEach(this.getPageNumbers(), (page) => {
  if (page === -1) {
    // 渲染 Text("...")
  } else {
    // 渲染 Button(页码)
  }
})

这种内联条件渲染避免了提取额外 @Builder 方法的冗余,让代码更加紧凑。


十、扩展与自定义指南

10.1 自定义列

如需新增列(如"操作人"“备注”),需要同时修改三个位置:

  1. 数据模型 BillItem.ets:添加新字段
  2. 表头 PaginatedBillTable.etsbuild() 方法中:新增 Text() 组件并设置宽度
  3. 数据行 BillRow@Builder 中:新增对应的 Text() 渲染逻辑

同时需要相应调整其他列的 width() 百分比,确保总宽度仍为 100%。

10.2 自定义分页大小

Index.ets 中修改 pageSize 的值即可:

pageSize: number = 20;  // 改为每页 20 条

也可在 PaginatedBillTable 的实例化时通过 @Prop 传入:

PaginatedBillTable({
  data: this.bills,
  pageSize: 20
})

10.3 数据源切换

mockBillsData() 替换为真实数据获取逻辑即可:

@State bills: BillItem[] = [];

aboutToAppear() {
  fetchBillData().then(data => {
    this.bills = data;
  });
}

组件的 @Prop 数据源变化后,所有计算属性会自动重新求值,UI 随之更新。

10.4 样式定制

  • 颜色:修改 #1A3A5C(表头/当前页码)、#0D2137(标题栏)等色值
  • 圆角:调整 borderRadius(6) 的值
  • 阴影:修改 shadow() 的参数
  • 字体:修改 fontSizefontWeight

十一、ArkTS 与常见框架对比

11.1 ArkTS vs Flutter

维度 ArkTS (ArkUI) Flutter
语言 TypeScript 生态 Dart
组件化 @Component struct class Widget
状态管理 @State/@Prop/@Link setState / Provider
布局 Column/Row/Flex Column/Row/Flex
列表 ForEach / List ListView.builder
构建工具 Hvigor Gradle / Dart
学习曲线 较低(TS 开发者友好) 中等(需学 Dart)

11.2 ArkTS vs SwiftUI

两者在理念上非常接近:都采用声明式语法、属性包装器/装饰器管理状态、结构化组件体构建 UI。ArkTS 的 @State 对应 SwiftUI 的 @State@Prop 对应 @Binding 的部分场景。

11.3 ArkTS vs Compose

ArkTS 的 build() 函数与 Jetpack Compose 的 @Composable 函数非常相似,都通过描述 UI 结构而非命令式操作 DOM 来构建界面。


十二、项目构建与运行

12.1 环境要求

  • DevEco Studio 6.0+(推荐 6.26.1)
  • HarmonyOS SDK API 24+
  • Node.js 20+(Hvigor 依赖)

12.2 构建命令

# 在 DevEco Studio 中直接运行
Open Project → Select D:/hongmeng/MyApplication64 → Run 'entry'

# 或使用命令行(需配置 Hvigor 环境)
hvigor assembleHap

12.3 预览模式

DevEco Studio 支持实时预览(Previewer),在 Index.ets 文件中点击预览按钮即可查看效果。预览模式下,ArkTS 代码会被编译为 TypeScript 并执行,支持组件的实时交互(点击按钮切换页码、滚动数据行等)。


十三、总结与展望

13.1 项目成果

本项目成功实现了:

  1. 一个完整的、可直接运行的 HarmonyOS 分页账单明细表应用
  2. 一个可复用的分页表格组件 PaginatedBillTable
  3. 一个合理的 ArkTS 项目结构(Model / Component / Page 三层)
  4. 一段可替换的模拟数据生成逻辑
  5. 一份完整的 ArkTS 开发踩坑记录

13.2 未来可扩展方向

  • 服务端分页:对接 RESTful API,支持大数据量场景
  • 排序功能:点击表头按日期/金额排序
  • 筛选功能:按日期范围/分类/状态筛选数据
  • 导出功能:将当前页或全部数据导出为 CSV/Excel
  • 编辑功能:支持行内编辑或弹窗编辑
  • 多级表头:如 “金额” 下拆分 “收入” 和 “支出”
  • 暗色模式:通过 @Provide / @Consume 实现主题切换
  • 国际化:支持多语言文案切换

13.3 对 ArkTS 开发的思考

通过这个项目,可以明显感受到 ArkTS 作为鸿蒙生态的原生开发语言,在 Web 前端开发者转型移动端开发方面具有天然优势。TypeScript 语法基础 + 声明式 UI 范式 + 响应式状态管理,使得从 Web 开发(React/Vue)过渡到鸿蒙开发的门槛大大降低。

同时,ArkTS 也有一些需要开发者特别注意的约束(如对象字面量规则、部分 API 可用性差异等),这些约束虽然增加了初期学习的成本,但换来了更强的类型安全和更优的运行时性能。随着鸿蒙生态的不断成熟,相信这些体验会越来越好。


附录 A:完整文件索引

文件 行数 职责
entry/src/main/ets/model/BillItem.ets 30 账单数据模型
entry/src/main/ets/components/PaginatedBillTable.ets 363 分页表格组件
entry/src/main/ets/pages/Index.ets 181 页面入口 + 模拟数据
entry/src/main/module.json5 50 模块配置
entry/build-profile.json5 33 构建配置

附录 B:关键技术决策记录

决策 选项 A 选项 B 最终选择
分页策略 服务端分页 前端切片 前端切片(数据量小)
金额类型 string number number(灵活计算)
日期格式 Date 对象 字符串 字符串(易序列化)
间距方案 Space() 组件 margin() margin()(精准控制)
状态着色 switch if/else if if/else if(兼容性好)
参数类型 内联对象 命名接口 命名接口(合规要求)

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐