HarmonyOS 5.0.0 首屏骨架屏怎么拆:加载态、空态和错误态不要混在一起
这个问题不是概念题,真正麻烦的是代码跑起来以后边界会变。页面可能退出,窗口可能变化,任务可能超时,资源可能失败。只看 API 名字很容易误判,所以我按“复现、拆边界、写封装、做验证”的顺序来讲。
版本和范围先说清楚
验证版本:HarmonyOS 5.0.0 及以上,示例按 API 12+ 的 ArkTS 写法组织;如果项目使用更高版本,需要按当前 SDK 编译提示调整 import 和权限声明。
这里不把版本说明藏在最后,因为很多 HarmonyOS 文章看起来能用,实际一编译才发现 API 范围不一致。我的习惯是先写清楚示例面向哪个版本,再写代码。这样后面读者照着改时,至少知道问题出在能力差异还是自己的封装边界。
问题怎么发生
首屏体验差,很多时候不是加载慢,而是状态表达混乱。加载中、无数据、加载失败都用同一个空白区域,用户不知道是在等,还是没有内容,还是出错了。
我会先把问题缩到最小,不急着上复杂封装。最小复现能回答一个问题:到底是能力不会用,还是工程边界没处理。如果最小复现都不稳定,后面封装只会把问题藏得更深。
案例一:只保留问题本身
先复现一个只用 loading 布尔值控制页面的写法。
@Stateloading:boolean=true@Statelist:Array<string>=[]build(){if(this.loading){Text('加载中')}else{List(){ForEach(this.list,item=>ListItem(){Text(item)})}}}这段代码重点看触发条件。能稳定复现以后,就不要再靠“感觉应该是这里”排查。尤其是异步、生命周期、多窗口、资源加载这些场景,触发顺序经常和我们想的不一样。
案例二:补上工程边界
第二个案例把 loading、empty、error 拆成明确状态。
enumPageState{Loading,Content,Empty,Error}classPageStateModel{state:PageState=PageState.Loading errorMessage:string=''setError(msg:string){this.state=PageState.Error;this.errorMessage=msg}}第二个案例开始处理工程边界。这里通常会多出一个控制对象,它不做业务,只做边界判断。这个设计看着朴素,但后面查问题会轻很多。
案例三:把验证结果留下来
只写代码还不够,我还会加一个很小的验证记录器。它的作用是让每一次验证都能留下结果,而不是靠口头说“我试过了”。
typeCheckResult={name:string,pass:boolean,detail:string}classVerifySheet{privateresults:Array<CheckResult>=[]add(name:string,pass:boolean,detail:string){this.results.push({name,pass,detail})}hasFail():boolean{returnthis.results.some(item=>!item.pass)}print(){this.results.forEach(item=>console.info(`${item.pass?'PASS':'FAIL'}${item.name}:${item.detail}`))}}我一般会记录五类结果:初始化是否正确、异常分支是否进入、页面退出后是否还有回调、重复触发是否被拦住、最终 UI 是否和状态一致。只要其中一项失败,就先回到对应模块修,不继续往下叠功能。
几种方案怎么选
| 方案 | 适合场景 | 风险 | 我的选择 |
|---|---|---|---|
| 临时写在页面里 | 快速验证 API | 后续容易漏释放、漏兜底 | 只用于最小复现 |
| 每个页面复制一套 | 页面差异很大 | 重复逻辑多,问题难统一修 | 不推荐长期用 |
| 抽成控制对象 | 多页面、多设备、长期维护 | 需要设计边界 | 推荐 |
我的判断标准很直接:如果这个能力会影响页面状态、异步回写、资源释放、审核材料或性能数据,就不要散落在页面里。把它收口成一个小对象,页面只表达用户动作和展示状态。
具体怎么验证
验证不要只点一遍主路径。我会按这个顺序做:冷启动进入页面,触发问题场景,快速退出再进入,切换窗口或设备形态,模拟失败分支,最后看日志和页面状态是否一致。
如果是性能或稳定性问题,还要看耗时和失败原因有没有记录。如果是上架审核相关问题,还要看截图、日志、权限说明是否能解释清楚。代码能跑只是第一步,能定位、能降级、能复盘才是完整闭环。
可以怎么复用
页面状态适合收口成 PageStateModel。它只负责表达当前状态,页面根据状态渲染骨架、内容、空态或错误态。
复用时不要急着做大框架。保留 start、update、release 或 run、cancel、accept 这类少量入口就够了。入口越少,边界越清楚,后面换页面、换设备、换需求时越不容易出事故。
以后怎么避免
这类问题以后遇到时,我会先问四个问题:有没有明确版本范围,有没有最小复现,有没有工程边界封装,有没有验证记录。四个问题都回答清楚,再进入正式开发。
写 HarmonyOS 技术文章也是同样逻辑。不要只搬概念,要把问题发生的路径、代码处理方式、方案取舍和验证结果讲清楚。这样文章才对开发者有用,代码也经得起别人照着试。