当前位置: 首页 > news >正文

HarmonyOS ArkTS 中的枚举:enum 完全使用指南与最佳实践

文章目录

    • 前言
    • 一、为什么要用枚举和常量?
      • 1.1 "魔法值"的危害
      • 1.2 本项目 Constants.ets 的设计
    • 二、TypeScript 枚举(enum)
      • 2.1 数字枚举
      • 2.2 字符串枚举
      • 2.3 常量枚举(const enum)
    • 三、项目 Constants.ets 深度解析
      • 3.1 查看 Constants 的使用模式
      • 3.2 为什么用 class 而不是 namespace 或 const?
    • 四、综合实战:用枚举重构状态管理
      • 4.1 加载状态枚举化
    • 总结

前言

在 HarmonyOS 项目中,你是否见过代码里散落着160.5'100%''GasStationPage'这样的"魔法值"?它们的意思令人困惑,修改时还容易遗漏。枚举(enum)常量类是解决这一问题的利器。本项目的Constants.ets就是一个标准的常量管理方案——本篇结合项目实践,深入讲解 TypeScript 枚举和常量模式。

一、为什么要用枚举和常量?

1.1 "魔法值"的危害

// ❌ 错误示范:魔法值满天飞if(status===2){// 2 是什么?谁知道?moveCamera(16);// 16 是缩放级别?还是别的?showDialog('loading');// 'loading' 这个字符串到处重复}// ✅ 正确示范:使用常量/枚举if(status===StationStatus.OPEN){// 一目了然!moveCamera(MapConstants.DEFAULT_ZOOM);showDialog(DialogType.LOADING);}

1.2 本项目 Constants.ets 的设计

本项目将所有"魔法值"集中管理:

// Constants.ets(节选)exportclassConstants{// 字体大小staticreadonlyFONT_SIZE_14=14;staticreadonlyFONT_SIZE_16=16;staticreadonlyFONT_SIZE_20=20;// 间距staticreadonlySPACE_6=6;staticreadonlySPACE_8=8;staticreadonlySPACE_12=12;staticreadonlySPACE_16=16;// 百分比尺寸staticreadonlyFULL_PERCENT='100%';staticreadonlyPERCENT_70='70%';// 路由名称// ...}

这种设计的优势:

  • 修改方便:只需改一处,全局生效
  • 可读性强FONT_SIZE_1616更清晰
  • 避免拼写错误:IDE 自动补全,不用担心写错

二、TypeScript 枚举(enum)

2.1 数字枚举

// 数字枚举:默认从0开始自增enumGasStationStatus{Unknown=0,// 未知状态Open=1,// 营业中Closed=2,// 已关闭Temporary=3// 临时停业}// 使用functiongetStatusText(status:GasStationStatus):string{switch(status){caseGasStationStatus.Open:return'营业中';caseGasStationStatus.Closed:return'已关闭';caseGasStationStatus.Temporary:return'临时停业';default:return'未知';}}constmyStatus:GasStationStatus=GasStationStatus.Open;console.log(myStatus);// 输出: 1(数字值)console.log(GasStationStatus[1]);// 输出: 'Open'(反向映射)console.log(getStatusText(myStatus));// 输出: '营业中'

2.2 字符串枚举

// 字符串枚举:更语义化,适合用于路由名称、事件名称等enumPageName{Main='MainPage',GasStation='GasStationPage',Settings='SettingsPage',Detail='StationDetailPage'}enumMapEventName{MarkerClick='markerClick',LocationClick='myLocationButtonClick',MapClick='mapClick'}// 使用functionnavigateTo(page:PageName,pageInfos:NavPathStack):void{pageInfos.pushPathByName(page,null);}// 替代之前的字符串字面量navigateTo(PageName.GasStation,this.pageInfos);// 等价于: this.pageInfos.pushPathByName('GasStationPage', null)

提示:字符串枚举没有反向映射功能(不能通过值找到键名),但调试时打印值更直观,推荐在路由名称、事件名等场景使用。

2.3 常量枚举(const enum)

// const enum:编译时直接内联值,运行时无额外对象,性能更好constenumZoomLevel{City=12,District=14,Street=16,Building=18,Max=21}// 编译后,ZoomLevel.Street 直接被替换为 16functionsetZoom(level:ZoomLevel):void{mapController.setZoom(level);// 实际上是 mapController.setZoom(16)}

三、项目 Constants.ets 深度解析

3.1 查看 Constants 的使用模式

// Constants.ets(完整示例,基于项目实际结构重建)exportclassConstants{// ===== 字体 =====staticreadonlyFONT_SIZE_14=14;staticreadonlyFONT_SIZE_16=16;staticreadonlyFONT_SIZE_20=20;staticreadonlyFONT_WEIGHT_400=400;staticreadonlyFONT_WEIGHT_500=500;staticreadonlyFONT_WEIGHT_700=700;// ===== 行高 =====staticreadonlyLINE_HEIGHT_19=19;staticreadonlyLINE_HEIGHT_21=21;staticreadonlyLINE_HEIGHT_27=27;// ===== 间距 =====staticreadonlySPACE_6=6;staticreadonlySPACE_8=8;staticreadonlySPACE_12=12;staticreadonlySPACE_16=16;staticreadonlyPADDING_LEFT_12=12;staticreadonlyPADDING_LEFT_16=16;staticreadonlyPADDING_RIGHT_12=12;staticreadonlyPADDING_RIGHT_16=16;staticreadonlyPADDING_TOP_8=8;staticreadonlyMARGIN_LEFT_16=16;staticreadonlyMARGIN_RIGHT_16=16;// ===== 尺寸 =====staticreadonlyFULL_PERCENT='100%';staticreadonlyPERCENT_70='70%';staticreadonlyGAS_STATION_IMAGE_WIDTH=48;staticreadonlyGAS_STATION_IMAGE_HEIGHT=48;staticreadonlyIMAGE_NEXT_WIDTH=16;staticreadonlyIMAGE_NEXT_HEIGHT=16;staticreadonlyIMAGE_BACK_WIDTH=24;staticreadonlyIMAGE_BACK_HEIGHT=24;// ===== 布局 =====staticreadonlyBORDER_RADIUS=12;staticreadonlyBORDER_RADIUS_16=16;staticreadonlySTROKE_WIDTH=0.5;staticreadonlyONE=1;staticreadonlyLAY_OUT_WEIGHT=1;// ===== 高度 =====staticreadonlyHEIGHT_80=80;staticreadonlyPAGE_BUILDER_HEIGHT=80;staticreadonlyMY_BUILDER_HEIGHT='85%';staticreadonlyMY_BUILDER_COLUMN_HEIGHT='50%';staticreadonlyBIND_SHEET_HEIGHT=200;// ===== 动画/定时 =====staticreadonlyTIME=500;// ===== 地图 =====staticreadonlyPOSITION_TOP=48;}

3.2 为什么用 class 而不是 namespace 或 const?

方案写法优缺点
class+static readonlyConstants.FONT_SIZE_16✅ 可组织、可 import、IDE 补全好
namespaceNS.FONT_SIZE_16✅ 类似效果,略显繁琐
顶层constexport const FONT_SIZE_16 = 16✅ 最简单,但容易命名冲突
enumFontSize.SIZE_16✅ 适合有限值域(状态、类型)

项目选择class + static readonly是因为:

  • 所有常量聚合在一个类下,方便按模块组织
  • import { Constants } from '...'使用方便
  • IDE 输入Constants.会显示所有可选常量

四、综合实战:用枚举重构状态管理

4.1 加载状态枚举化

// 定义枚举enumLoadStatus{Idle='idle',// 初始状态Loading='loading',// 加载中Success='success',// 成功Empty='empty',// 数据为空Error='error'// 失败}enumSortOrder{ByDistance='distance',ByPrice='price',ByRating='rating'}enumStationBrand{All='全部',Sinopec='中国石化',CNPC='中国石油',Shell='壳牌',BP='BP'}// 使用枚举的组件@Entry@Componentstruct EnumDemoPage{@StateloadStatus:LoadStatus=LoadStatus.Idle;@StatesortOrder:SortOrder=SortOrder.ByDistance;@StateselectedBrand:StationBrand=StationBrand.All;// 状态文本映射getStatusText():string{conststatusMap:Record<LoadStatus,string>={[LoadStatus.Idle]:'等待加载',[LoadStatus.Loading]:'加载中...',[LoadStatus.Success]:'加载成功',[LoadStatus.Empty]:'暂无数据',[LoadStatus.Error]:'加载失败'};returnstatusMap[this.loadStatus];}getStatusColor():string{constcolorMap:Record<LoadStatus,string>={[LoadStatus.Idle]:'#999999',[LoadStatus.Loading]:'#1A6FF5',[LoadStatus.Success]:'#52C41A',[LoadStatus.Empty]:'#FA8C16',[LoadStatus.Error]:'#FF4D4F'};returncolorMap[this.loadStatus];}build(){Column({space:16}){// 状态显示Text(this.getStatusText()).fontSize(18).fontWeight(FontWeight.Bold).fontColor(this.getStatusColor())// 品牌筛选(枚举驱动)Scroll(){Row({space:8}){ForEach(Object.values(StationBrand),(brand:string)=>{Text(brand).fontSize(13).fontColor(this.selectedBrand===brandasStationBrand?'#FFFFFF':'#666666').padding({left:12,right:12,top:6,bottom:6}).backgroundColor(this.selectedBrand===brandasStationBrand?'#1A6FF5':'#F0F0F0').borderRadius(16).onClick(()=>{this.selectedBrand=brandasStationBrand;})})}.padding({left:16})}.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off)// 排序选项(枚举驱动)Row({space:8}){ForEach([{key:SortOrder.ByDistance,label:'按距离'},{key:SortOrder.ByPrice,label:'按价格'},{key:SortOrder.ByRating,label:'按评分'},],(item:Record<string,string>)=>{Text(item['label']asstring).fontSize(13).fontColor(this.sortOrder===item['key']asSortOrder?'#1A6FF5':'#666666').fontWeight(this.sortOrder===item['key']asSortOrder?FontWeight.Bold:FontWeight.Normal).onClick(()=>{this.sortOrder=item['key']asSortOrder;})})}// 模拟加载状态切换Row({space:8}){ForEach(Object.values(LoadStatus),(status:string)=>{Button(status).fontSize(11).height(30).backgroundColor('#F0F0F0').fontColor('#333333').borderRadius(15).onClick(()=>{this.loadStatus=statusasLoadStatus;})})}}.padding(20).width('100%').height('100%').backgroundColor('#F5F7FA')}}

总结

枚举和常量是消灭"魔法值"、提升代码可读性的利器。enum适合有限值域的类型(状态、排序、品牌),class + static readonly适合聚合大量项目级常量(本项目 Constants.ets 的方案)。合理运用枚举不仅让代码意图清晰,还能借助 TypeScript 类型系统在编译时发现错误——这正是静态类型语言的核心价值所在。

http://www.jsqmd.com/news/980960/

相关文章:

  • 科伦坡租房决策专家系统:规则引擎+动态知识图谱实践
  • 别再死记硬背公式了!用Python+NumPy手把手模拟正交解调全过程(附代码)
  • 宁波伯爵+沛纳海手表专业回收,26年精选回收店铺排行榜推荐 - 莘州文化
  • 制造业电子数据交换EDI软件落地价值|详细解答
  • 有哪些高效的NOI省选专题题目解题技巧
  • YOLOv11涨点改进| TIP 2025 |独家特征融合改进篇| 引入DFAM双特征聚合模块,通过局部纹理先验强化边缘、轮廓信息,助力小目标检测、RGB-D目标检测、多模态融合目标检测有效涨点
  • 【论文复现】基于行波理论的输电线路故障诊断方法研究附Simulink仿真
  • 大模型+Skills=MCP?深度解析智能体核心组件,告别概念混乱!
  • 京华ALTDH382SS PCIe转RS232串口卡原厂驱动包(Win7/Win10双系统支持)
  • 太阳能领域情感分析实战:NLP舆情监测轻量级方案
  • 信息疫情与社会经济因素的动态关联及防控策略
  • Keyboard Chatter Blocker:3分钟搞定键盘连击问题,让你的机械键盘重获新生!
  • 基于扩散模型的 UI 图标生成:风格一致性控制与工程落地
  • 攀枝花帝舵+江诗丹顿手表专业回收,26年精选回收店铺排行榜推荐 - 莘州文化
  • Java开发工程师全景解读:岗位职责·城市薪资·发展前景·高考志愿填报指南(2026版)
  • Trae CN切换MiniMax-M3模型
  • 沥青类防水卷材厂家选购指南:不同工程场景怎么选 - 资讯快报
  • WinUI 3项目实战:手把手教你用C#和Windows App SDK打造一个Fluent Design风格的应用界面
  • 2026最新 孩子英语发音不标准 实用的发音纠正听说软件推荐
  • 鄂州市2026年黄金回收白银回收铂金回收变卖,5 家靠谱贵金属门店实地测评汇总 - 干豆腐啊
  • 四角色多智能体讨论系统:用LangGraph构建结构化AI协作流程
  • 光伏并网逆变器低电压穿越技术研究附Simulink仿真
  • 淮安劳力士+欧米茄手表专业回收,26年精选回收店铺排行榜推荐 - 莘州文化
  • 从攻击者视角看DVWA XSS:Cookie窃取背后的原理、危害与防御思考
  • Tiktokenizer:终极指南 - 如何可视化分析DeepSeek R1和Qwen2.5等主流LLM分词器
  • 【虚拟机】ALmaLinux安装
  • COM3D2.MaidFiddler:3分钟上手的游戏实时编辑器完全指南
  • 莲湖区家政公司分析:靠谱家政电话与家电空调维修参考 - 资讯速览
  • 小程序毕设选题推荐:基于springboot+vue的微信小程序的个人运动健康管理平台的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 5分钟掌握VRM插件:Blender虚拟角色制作终极指南