HarmonyOS 7 ArkUI 实战 06|Tabs 别重复加载
页签切换、缓存与懒加载很多页面第一版都不难。照着设计稿写几个Row、Column再把按钮事件接上模拟器里一跑看起来已经差不多了。真正麻烦的是第二轮需求这里加筛选那里加 loading再补一个空状态产品又说横向空间不够。页面很快就从“能跑”变成“不敢动”。这一篇我们就处理一个很具体的问题页签切换、缓存与懒加载。不堆 API也不为了显得高级去造框架。先把问题拆开再写一个能运行的最小版本最后补上真实项目里最容易漏掉的边界。1. 先别急着写代码看看问题到底在哪ArkUI 是声明式 UI。这个词听着有点抽象其实可以理解成一句话页面应该描述“当前状态下长什么样”而不是到处写命令去手工改界面。很多页面后期难维护不是因为 ArkTS 难而是三个东西混在了一起页面结构、业务状态、交互流程。一个点击事件里既改变量又发请求又拼参数还顺手控制弹窗短期很快后面排错就很痛苦。我写业务页时通常先画三个框页面有什么区域哪些数据会变化变化由谁触发。十分钟想清楚往往比直接敲一小时代码更省时间。2. 先做最小可运行版本下面这段代码只保留本篇最核心的结构State currentIndex: number 0 State loaded: boolean[] [true, false, false] Tabs({ index: this.currentIndex }) { TabContent() { TodoPage() }.tabBar(待办) TabContent() { DonePage() }.tabBar(已完成) TabContent() { MinePage() }.tabBar(我的) } .onChange((index: number) { this.currentIndex index this.loaded[index] true })这里不要急着抽象。先在 DevEco Studio 里跑起来看模拟器上的行为是否符合预期。教程里最容易出现的问题就是代码看着“架构很好”结果复制进工程缺一堆上下文。我们反过来先保证核心链路成立。3. 为什么这样写会更稳关键不是少写几行而是职责清楚。页面知道自己当前是什么状态组件知道自己负责显示什么事件只负责触发变化。例如用户点一次按钮如果背后有异步请求页面至少要知道“正在请求”。否则连续点三次就可能真的发三次请求。再比如列表刷新时如果刷新和加载更多共用一个模糊的loading很容易出现底部正在加载时整个页面突然被遮住。状态命名也别太随意。flag1、isShow2这种变量写的时候快两周后自己都不知道是什么意思。宁愿长一点也写成refreshing、showFilterPanel、pageStatus。4. 把正常路径和异常路径一起写只写成功流程是 Demo把失败、空数据和恢复流程补齐才接近项目。异步方法我一般会保留完整的try / catch / finally。try负责正常请求catch决定失败后页面怎么表现finally则非常适合恢复 loading。这样即使请求抛异常也不至于让按钮永远停在“处理中”。async loadData() { if (this.loading) return this.loading true try { const data await this.requestData() this.items data } catch (err) { console.error([TabsPage] loadData failed) } finally { this.loading false } }注意第一行的防重复判断。它看起来不起眼但在真实业务里特别有用。5. UI 状态不要越堆越多另一个常见问题是 boolean 越写越多State loading: boolean false State empty: boolean false State error: boolean false State success: boolean false这四个变量理论上能组合出很多状态但业务真正允许的通常只有几个。万一loading和error同时变成true到底显示谁互斥状态更适合收口成枚举enum PageStatus { Idle, Loading, Success, Empty, Error } State pageStatus: PageStatus PageStatus.Idle这样页面在某一时刻只处于一个明确状态阅读和排错都会轻松很多。6. 组件到底什么时候拆不是代码超过 100 行就必须拆。更实用的判断有三个这个区域有没有独立职责有没有自己的局部状态以后会不会复用满足其中一个就值得考虑拆组件。反过来一个只有两行文字、没有状态、也不会复用的区域硬拆成单独文件反而增加阅读成本。我更习惯把页面看成“组织者”。页面负责把标题区、筛选区、内容区组合起来真正的细节交给业务组件。网络请求、数据转换、持久化则尽量不要全部塞在页面文件里。7. DevEco Studio 里怎么排查“页面不对”遇到 UI 没变化先别怀疑框架。按这个顺序查第一步看点击事件有没有触发。第二步看状态值是不是真的改了。第三步看当前 UI 是否依赖这个状态。第四步如果有异步逻辑看异常是不是提前打断了后面的代码。日志建议带上页面名console.info([TabsPage] start) console.info([TabsPage] status changed)别一次打印一个巨大对象。真正出问题时日志越多不一定越容易看。8. 再往真实业务靠一步页签切换、缓存与懒加载放到真实项目里通常还会碰到页面重新进入、窗口尺寸变化、接口慢、用户连续操作、数据为空等情况。所以写完“正常效果”以后我会故意做几次破坏性测试断网再点一次连续点五次让接口返回空数组切到别的页面再回来把文案改得特别长。很多布局和状态问题这时候才会暴露。9. 不要为了工程化而工程化项目里还有一种反方向的问题刚写两个页面就开始设计万能基类、万能弹窗、万能列表。抽象应该来自重复而不是来自想象。业务还没稳定时先写清楚通常比先写通用更重要。等两三个页面真的出现相同结构再抽公共组件边界会准确很多。资源也是一样。会重复出现的颜色、尺寸、文案可以逐步收口只出现一次的东西没必要第一天就建立十层配置。10. 提交前做一次快速自检我一般会检查这些事情首次进入是否正常连续点击是否重复请求loading 能不能恢复空数据有没有页面失败后能不能重试长文本会不会顶坏布局列表数据多起来以后是否明显卡顿页面重新进入后状态是不是预期值。这些检查没有炫技成分却非常接近线上真正会出现的问题。最后总结这一篇真正要练的不是记 API而是形成一个稳定顺序先拆页面结构再确定状态归属然后写交互最后补异常路径。HarmonyOS 7 的 ArkUI 本身并不难页面越写越乱通常是因为结构和状态没有先想清楚。把这个顺序养成习惯后面无论写列表、表单、Tabs 还是复杂业务页都会顺很多。

相关新闻

130_dq轴电感交叉耦合在高速区的忽略代价

130_dq轴电感交叉耦合在高速区的忽略代价

那个把电流环带宽推到2kHz的夜晚 前两年做一个高速永磁同步电机的驱动器项目,额定转速折算到电频率大概在1200Hz左右,弱磁区域还要再往上拉。当时接手的时候,前一位工程师已经把电流环整定完了,阶跃响应看起来挺漂亮,带宽标称2kHz,PI参数算得工工整整。我拿到手测了一下…

2026/10/15 14:27:37 阅读更多 →
使用EasyExcel实现高效Excel数据导出与ZIP打包

使用EasyExcel实现高效Excel数据导出与ZIP打包

1. 项目背景与需求拆解最近在开发一个数据报表导出功能时,遇到了一个典型需求:用户上传的Excel文件每行数据需要转换成独立表格,最终将所有表格打包成ZIP供下载。这种场景在数据分发、报表生成等业务中很常见。传统POI方案在处理大批量数据时…

2026/10/15 14:26:35 阅读更多 →
Flutter在OpenHarmony上的跨平台开发实战

Flutter在OpenHarmony上的跨平台开发实战

1. 项目背景与核心价值Flutter作为Google推出的跨平台开发框架,近年来在移动应用开发领域获得了广泛关注。而OpenHarmony作为新兴的分布式操作系统,其生态建设正处于快速发展阶段。将Flutter应用于OpenHarmony平台开发,不仅能够复用现有的Flu…

2026/10/15 14:26:35 阅读更多 →

最新新闻

订单系统性能优化实战:从故障定位到架构升级

订单系统性能优化实战:从故障定位到架构升级

1. 事故背景与问题定位那天凌晨2点17分,我被一连串急促的报警短信惊醒。生产环境的核心订单服务响应时间从平时的200ms飙升到8秒以上,错误率突破30%。打开监控大盘时,整个服务集群的CPU利用率曲线像悬崖般陡峭上升,部分节点已经触…

2026/10/15 15:07:52 阅读更多 →
JVM和JMM高频面试题:底层原理与并发机制全解析

JVM和JMM高频面试题:底层原理与并发机制全解析

正值金三银四面试季,不少朋友跟我反馈,Java面试被问“跟我讲下JVM和JMM”时,第一反应是脑内循环“JVM是虚拟机,JMM是内存模型”,然后……就没有然后了。这道题其实是个典型的高频入口题,面试官既可以考察你…

2026/10/15 15:07:52 阅读更多 →
Windows本地Kubernetes搭建指南:WSL2下Kind与Minikube对比实战

Windows本地Kubernetes搭建指南:WSL2下Kind与Minikube对比实战

1. 为什么要在Windows上折腾本地Kubernetes1.1 本地K8s的真实需求场景很多人第一次接触Kubernetes都是在公司的测试集群或者云厂商的托管服务上,点点鼠标就能拿到一个能用的集群。但一旦回到自己的Windows笔记本上,想复现一个YAML、验证一个Operator的行…

2026/10/15 15:07:52 阅读更多 →
Python爬虫实战:Goodreads书单数据抓取与清洗

Python爬虫实战:Goodreads书单数据抓取与清洗

1. 项目背景与核心需求 最近在整理个人阅读清单时,发现Goodreads的Listopia功能提供了大量优质书单资源。但手动记录每本书的书名、作者和评分实在太费时间。作为Python开发者,我决定写一个爬虫来自动化这个过程,并实现数据清洗和持久化存储。…

2026/10/15 15:07:52 阅读更多 →
Goodreads书单爬虫实战:高效采集与数据清洗技巧

Goodreads书单爬虫实战:高效采集与数据清洗技巧

1. 项目背景与核心需求Goodreads作为全球最大的书评和推荐网站之一,其Listopia功能汇集了大量用户创建的主题书单。这些书单数据对于图书市场分析、读者偏好研究或个人阅读规划都具有重要价值。但网站并未提供结构化数据导出功能,手动收集效率极低。这个…

2026/10/15 15:07:52 阅读更多 →
SSM框架在酒吧管理系统中的实践与优化

SSM框架在酒吧管理系统中的实践与优化

1. 项目概述与核心价值酒吧后台管理系统是典型的餐饮娱乐行业信息化解决方案,采用JavaWeb技术栈实现。这个系统本质上解决的是夜间娱乐场所运营中的三大痛点:人工记录易出错、营业数据不透明、多岗位协作低效。我在2018年参与过某连锁酒吧集团的系统升级…

2026/10/15 15:06:48 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →