做鸿蒙 App 一个月:10 个 ArkUI 大坑

做鸿蒙 App 一个月:10 个 ArkUI 大坑
在这里插入图片描述

子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名)

大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:掘金、知乎、ZEEKLOG、简书
创作特点:实战导向、源码拆解、少空谈多落地
文章状态:长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”

持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱

文章目录

引言

最近一个月,我从传统 App(Android / Flutter)转向开发鸿蒙应用,用 ArkUI(ArkTS) 写了一个完整的项目。

一开始我以为:

“不就是一个声明式 UI 框架吗?”

但真正写下来才发现,ArkUI 的设计和传统 App 差别非常大

一个月下来,我踩了不少坑。

坑 1:状态没有用 @State,UI 不更新

很多刚写 ArkUI 的开发者,会这样写代码:

struct CounterPage { count:number=0build(){Column(){Text(`count: ${this.count}`)Button("Add").onClick(()=>{this.count++})}}}

你会发现:点击按钮 UI 不更新。

原因很简单:ArkUI 的 UI 是 响应式的,只有被声明为状态的变量才会触发刷新。

正确写法:

@Entry@Component struct CounterPage {@State count:number=0build(){Column(){Text(`count: ${this.count}`)Button("Add").onClick(()=>{this.count++})}}}

核心原则:

UI 依赖的数据必须是状态。

坑 2:组件参数忘记用 @Prop

很多人写组件时会这样写:

@Component struct UserCard { name:stringbuild(){Text(this.name)}}

在父组件使用:

UserCard({ name:"Tom"})

结果编译报错,原因是:ArkUI 的组件参数必须使用 @Prop 标记。

正确写法:

@Component struct UserCard {@Prop name:stringbuild(){Text(this.name)}}

如果参数会变化,可以用:

@Link 

@Observed 

坑 3:列表渲染性能问题

很多开发者第一次写列表会这样:

Column(){ForEach(this.list,(item)=>{Text(item.name)})}

如果列表很多:

  • UI 会卡顿
  • 滑动不流畅

因为 Column 会一次性渲染所有内容。正确做法:

使用 LazyForEach

List(){LazyForEach(this.list,(item)=>{ListItem(){Text(item.name)}})}

优势:

  • 按需渲染
  • 性能更好

坑 4:组件状态共享混乱

很多人一开始会滥用 @State,例如:

@State userInfo: User 

然后在多个组件之间传递,结果导致:

  • 状态同步混乱
  • UI 更新异常

正确做法是:使用 @Provide / @Consume,例如父组件:

@Provide userInfo: User ={ name:"Tom"}

子组件:

@Consume userInfo: User 

这样可以实现 跨组件状态共享

坑 5:生命周期理解错误

很多 Android / Flutter 开发者会寻找类似:

onCreate onResume 

这样的生命周期。ArkUI 其实提供了不同机制:

aboutToAppear(){console.log("页面即将出现")}aboutToDisappear(){console.log("页面消失")}

例如加载数据:

aboutToAppear(){this.loadData()}

坑 6:页面路由方式不同

很多开发者会寻找传统 Router,ArkUI 的导航方式是:

router.pushUrl() 

例如:

import router from'@ohos.router' router.pushUrl({ url:'pages/detail'})

返回:

router.back()

坑 7:UI 布局思维没转过来

很多 Android 开发者习惯:

LinearLayout RelativeLayout ConstraintLayout 

ArkUI 的布局更接近 Flexbox 思维,例如:

Row(){Text("Left")Blank()Text("Right")}

Blank() 相当于 flex spacer

坑 8:组件拆分不合理

很多人会写出一个 巨大的页面组件

struct HomePage {// 1000 行代码}

正确方式是 组件拆分

HomePage ├─ Banner ├─ UserInfo ├─ MenuGrid ├─ FeedList 

例如:

@Component struct Banner {build(){Text("Banner")}}

坑 9:动画系统不熟悉

ArkUI 内置动画非常简单:

.animateTo({ duration:300},()=>{this.scale =1.2})

例如点击放大:

Button("Click").onClick(()=>{animateTo({ duration:300},()=>{this.scale =1.2})})

坑 10:没有理解声明式 UI

这是 最核心的坑,很多开发者还在用 命令式思维

修改 UI 刷新 UI 重新渲染 UI 

而 ArkUI 的核心思想是:

UI = State

例如:

Text(this.isLogin ?"已登录":"未登录")

只需要改变状态:

this.isLogin =true

UI 会自动更新。

总结

写了一个月鸿蒙应用,我最大的感受是:ArkUI 的学习成本不在语法,而在思维。

你需要从:命令式 UI,转变为声明式 UI + 状态驱动 UI。理解这一点之后,很多问题都会迎刃而解。

如果你刚开始学习鸿蒙开发,建议重点理解三件事:

1️⃣ 状态管理
2️⃣ 声明式 UI 思维
3️⃣ 组件化设计

掌握这三点,ArkUI 会顺手很多。

Read more

JavaScript DOM 核心操作:从内容到节点的实战指南

JavaScript DOM 核心操作:从内容到节点的实战指南

DOM(文档对象模型)是前端开发中操作页面结构、内容和样式的核心,本文聚焦 DOM 中元素内容、属性、样式的读写修改,以及节点的增删改,结合实战示例讲解核心用法与最佳实践。 一、操作元素内容 元素内容操作分为纯文本处理和带 HTML 结构的处理,核心使用 innerText 和 innerHTML 两个属性,二者特性对比如下: 方法识别 HTML 标签保留换行 / 空格标准性适用场景innerText❌❌非标准(IE)仅读取 / 修改纯文本innerHTML✅✅W3C 标准读取 / 修改带 HTML 结构的内容 1. innerText:纯文本操作 仅处理文本内容,会忽略 HTML 标签和源码中的换行 / 空格,适合简单文本读写。 // 读操作:获取元素纯文本内容 var text = element.innerText;

By Ne0inhk
JAVA API (三):从基础爬虫构建到带条件数据提取 —— 详解 URL、正则与爬取策略

JAVA API (三):从基础爬虫构建到带条件数据提取 —— 详解 URL、正则与爬取策略

个人主页-爱因斯晨 文章专栏-Java学习 相关文章:API (一) 相关文章:API(二) 持续努力中,感谢支持 一、爬虫基础 (一)爬虫的基本概念 * 定义:爬虫是按照一定规则自动抓取网络信息的程序,在 Java 环境下,可借助URL、HttpURLConnection等 API 来实现。 * 应用场景:广泛应用于数据采集,如电商平台的价格监控、各类新闻的聚合;还可用于信息分析,如舆情监测等。 (二)Java 实现简单爬虫的步骤 建立网络连接:利用URL类确定目标网页的地址,再通过openConnection()方法获取HttpURLConnection对象。 URL url =newURL("https://example.com");HttpURLConnection conn =(HttpURLConnection) url.openConnection(); 设置请求参数:

By Ne0inhk
基于Milvus与混合检索的云厂商文档智能问答系统:Java SpringBoot全栈实现

基于Milvus与混合检索的云厂商文档智能问答系统:Java SpringBoot全栈实现

基于Milvus与混合检索的云厂商文档智能问答系统:Java SpringBoot全栈实现 面对阿里云、腾讯云等厂商海量的产品文档、规格参数与价格清单,如何构建一个精准、高效的智能问答系统?本文将为你揭秘从技术选型到生产部署的完整方案。 云服务商的产品生态系统日益庞大,相关的技术文档、规格参数、定价清单等文档数量急剧增长。传统的文档查找方式已无法满足开发者和运维人员快速获取准确信息的需求。 基于检索增强生成(RAG)的智能问答系统成为解决这一难题的有效方案。本文将详细介绍如何使用 Java SpringBoot 和 Milvus 向量数据库,构建一个面向云厂商文档的高效混合检索问答系统。 一、核心挑战与架构选型 云厂商文档具有鲜明的技术特点,这些特点直接影响了我们的技术选择: 1. 高度结构化:包含大量技术规格表、价格矩阵和配置参数 2. 专业术语密集:如“ECS.g6.2xlarge”、“对象存储每秒请求数”等精确术语 3. 多格式混合:Markdown、PDF、Word、TXT等格式并存 4. 版本频繁更新:产品迭代快,文档需要及时同步

By Ne0inhk
【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

目录 一、为什么需要 Disruptor?—— 背景与问题 二、核心设计思想 三、核心组件与原理 1. 环形缓冲区(Ring Buffer) 2. 序列(Sequence) 3. 序列屏障(Sequence Barrier) 4. 等待策略(Wait Strategy) 5. 事件处理器(EventProcessor) 6. 生产者(Producer) 四、工作流程示例(单生产者 -> 单消费者) 五、多消费者与依赖关系 六、总结:Disruptor 高性能的秘诀 一、为什么需要 Disruptor?—— 背景与问题 在高并发编程中,传统的队列(如 java.

By Ne0inhk