news 2026/7/1 10:08:58

ArkTS 严格模式实战:用类型模型守住 HarmonyOS 页面契约

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ArkTS 严格模式实战:用类型模型守住 HarmonyOS 页面契约

ArkTS 严格模式对类型非常敏感。项目里一开始如果到处写临时对象、动态字段和Record<string, ...>,后面很容易遇到编译错误,或者页面之间字段对不上。

这个桌面卡片工具项目把共享模型统一放在AppModels.ets,再由服务层输出页面需要的视图模型。这样页面只关心“展示什么”,不关心底层数据从模板、本地卡片还是回收站来。

为什么先建模型

项目里有很多页面都在展示卡片:

  • 首页的“我的卡片”
  • 分类页的分类概览和热门卡片
  • 卡片详情页的摘要卡
  • 样式页的样式卡
  • 管理页的卡片列表
  • 桌面 Form 的摘要数据

如果每个页面自己定义字段,很快会出现字段不一致:

title subtitle value badge categoryId templateId cardId imageKey

这些字段有些用于 UI,有些用于路由,有些用于资源映射。项目选择把它们抽成固定 interface。

ShowcaseCardModel:通用卡片展示模型

ShowcaseCardModel是页面复用最高的模型:

export interface ShowcaseCardModel { id: string; title: string; subtitle: string; tone: ToneName; value?: string; footer?: string; badge?: string; route?: string; imageKey?: string; cardId?: string; templateId?: string; categoryId?: CardCategoryId; }

它同时服务展示和跳转:

  • titlesubtitlevaluefooter负责文案。
  • tone负责颜色主题。
  • imageKey负责图片资源。
  • cardIdtemplateIdcategoryId负责点击后的语义。

这里没有把所有字段都做成必填。因为不同页面使用同一个卡片组件时,信息密度不同:详情页有完整卡片,分类概览可能只需要分类入口,样式页则更关注imageKey

MenuRowModel:列表行也需要明确目标参数

列表项模型和卡片模型类似,但更适合单行结构:

export interface MenuRowModel { id: string; mark: string; title: string; subtitle: string; tone: ToneName; value?: string; route?: string; tabId?: string; imageKey?: string; cardId?: string; templateId?: string; }

项目里曾经出现过“点击列表进详情但参数丢失”的问题。修复后的关键是:只要列表项会跳转详情,就必须带明确的cardIdtemplateId

页面处理时也按优先级判断:

const cardId: string = item.cardId ? item.cardId : ''; if (cardId.length > 0) { router.pushUrl({ url: RoutePaths.cardDetail, params: { cardId: cardId } }); return; } const templateId: string = item.templateId ? item.templateId : item.id;

这样用户卡片和内置模板可以共用同一个详情页,但不会混成“空白 fallback”。

CardDraftModel 和 CardRecordModel:草稿和真实记录分开

编辑页使用的是CardDraftModel,保存后的数据才是CardRecordModel

export interface CardDraftModel { id: string; templateId: string; title: string; subtitle: string; detail: string; value: string; footer: string; badge: string; tone: ToneName; categoryId: CardCategoryId; favorite: boolean; } export interface CardRecordModel extends CardDraftModel { active: boolean; usageCount: number; createdAt: string; updatedAt: string; lastUsedAt: string; sceneTags: string[]; }

这个拆法有两个实际价值:

  1. 编辑页不需要伪造createdAtusageCount这类字段。
  2. 服务层保存时可以统一补齐运行时状态,页面不会乱写元数据。

枚举类型不要直接展示给用户

项目中的分类 ID 是稳定内部 key:

export type CardCategoryId = 'daily' | 'countdown' | 'health' | 'tool' | 'life' | 'study' | 'fun' | 'system';

这些 key 适合做持久化、筛选和路由参数,但不适合直接显示。详情页展示“类别”时没有直接渲染countdown,而是调用:

appDataService.getCategoryLabel(this.card.categoryId)

这样用户看到的是“倒计时”“健康”“工具”这类中文文案。内部 key 和用户文案分离,是多语言、改文案和保持数据兼容的基础。

ArkTS 严格模式下的几个实践

这个项目里形成了几条比较稳定的规则:

  1. ForEach的 item 和 key 函数都显式标注类型。
  2. 共享常量优先用静态类或具名 interface。
  3. 自定义组件回调字段避免叫onClickonChange这类容易和内置属性混淆的名字。
  4. 避免在 UI Builder 中声明局部constlet,需要中间值时抽 helper。
  5. 不直接渲染内部枚举 key,服务层负责转成用户文案。

例如首页分类卡片:

ForEach(appDataService.getCategoryCards('recommend', this.categoryQuery), (item: ShowcaseCardModel) => { GridItem() { ShowcaseCard({ item: item, compactBadge: true }) } }, (item: ShowcaseCardModel) => item.id )

这比省略类型更啰嗦,但在严格模式下更稳。

视图模型比原始数据更适合页面

服务层可以把原始卡片、模板目录、分类元信息统一转换成页面模型。以详情页为例:

export interface CardDetailViewModel { card: CardRecordModel; isTemplate: boolean; }

页面只需要根据isTemplate决定按钮:

  • 模板:显示“添加到我的卡片”
  • 我的卡片:显示“编辑当前卡片”
  • 空白 fallback:显示“新建卡片”

底层是模板还是用户数据,页面不直接判断。

小结

ArkTS 项目里,类型模型不是可有可无的“文档”,而是页面契约。这个桌面卡片工具项目用AppModels.ets把卡片、列表、草稿、记录、统计、备份、提醒都统一建模,再由AppDataService输出页面需要的视图模型。

这样写的直接收益是:页面少猜字段,路由少丢参数,资源映射更稳定,严格模式下的编译错误也更容易定位。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 10:07:13

Kiran计算器数学引擎原理:任意精度计算实现解析

Kiran计算器数学引擎原理&#xff1a;任意精度计算实现解析 【免费下载链接】kiran-calculator This is a calculator with three modes which contain standard, science and programmer. 项目地址: https://gitcode.com/openeuler/kiran-calculator 前往项目官网免费下…

作者头像 李华
网站建设 2026/7/1 10:03:37

uml中的泳道图一般干什么用

UML 中的泳道&#xff08;Swimlane&#xff09;通常用在活动图&#xff08;Activity Diagram&#xff09;里&#xff0c;核心作用是把复杂的流程按责任主体&#xff08;角色、部门、系统、对象等&#xff09;切分成并行的纵向或横向区域&#xff0c;让"谁做了什么"一…

作者头像 李华
网站建设 2026/7/1 10:03:02

XUnity.AutoTranslator完整指南:打破语言障碍,畅玩全球Unity游戏

XUnity.AutoTranslator完整指南&#xff1a;打破语言障碍&#xff0c;畅玩全球Unity游戏 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾因为语言障碍而错过精彩的日文、英文或其他外语游戏&…

作者头像 李华
网站建设 2026/7/1 10:02:03

2026年618农资行业复盘报告:淡季分化、刚需集中、渠道重塑

一、整体复盘概况2026年618农资大促周期覆盖6月1日-6月23日&#xff0c;贯穿夏管尾声、秋肥前置备货初期&#xff0c;整体呈现行情分化、刚需采购、谨慎囤货、线上渗透提速的核心特征。不同于往年大促全面走量的态势&#xff0c;本年度农资618无全面爆单行情&#xff0c;市场处…

作者头像 李华
网站建设 2026/7/1 10:01:25

系统规划与管理师-矛盾论与实践论在系统规划与管理中的应用

一、引言&#xff08;一&#xff09;核心概念定义系统科学与哲学方法论是软考高级系统规划与管理工程师知识体系的基础理论模块&#xff0c;其中矛盾论、实践论是马克思主义哲学与系统管理实践结合的核心指导思想。矛盾论是基于唯物辩证法对立统一规律的矛盾分析方法论&#xf…

作者头像 李华
网站建设 2026/7/1 10:01:17

问题管理化技术中的问题识别问题分析问题解决

问题管理化技术是现代组织管理中的核心工具&#xff0c;其核心流程包括问题识别、问题分析与问题解决。这一技术不仅能够帮助组织快速应对突发状况&#xff0c;还能通过系统化的方法提升决策效率。在竞争激烈的市场环境中&#xff0c;能否高效解决问题往往决定了企业的成败。本…

作者头像 李华