AI写鸿蒙UI:10个跑崩8个,剩下2个看运气
先把结论扔出来,省得你翻半天:
让 AI 写 ArkTS 的核心 UI 组件,10 个里面 8 个跑不起来。剩下 2 个里面还有 1 个会在真机上崩溃。
我手头在做的 App 雷达鸭(鸿蒙版)就是这个测试场。三个月下来,我把 AI 自动补全在核心 UI 编码时直接关了------但 AI 写注释、写单测、写样板路由代码比人快 3 倍,这事我天天用。
这篇不是劝退 AI,是劝你把 AI 用对地方。
一、AI 写 ArkTS 组件最常翻车的三个地方
我把 AI 写错的代码攒了一堆,按错误类型分了三档。看下面这段 AI 生成的「瀑布流卡片组件」,你猜错在哪:
typescript
// AI 生成的版本(看起来没问题,跑起来崩)
@Component
struct WaterfallCard {
@State item: CardItem = new CardItem()
@Builder ItemBuilder() {
Column() {
Text(this.item.title)
Image(this.item.cover)
}
}
build() {
List({ space: 10 }) {
ForEach(this.dataSource, (item: CardItem) => {
ListItem() {
this.ItemBuilder() // ❌ 错误 1:Builder 不能在 ListItem 里直接用
}
})
}
}
}
错误有三:
Builder装饰器的方法不能直接作为组件在ListItem里实例化 ,必须用if/else或独立组件包裹。ForEach没传第三个参数(item, index) => key------鸿蒙的ForEach第二个参数允许省略 key,但省略后无法触发 UI 刷新,这是个隐性 bug。@State item应该是@State @Watch('onItemChange') item,但 AI 不知道我需要监听 item 变化去请求图片清晰度。
AI 错在哪?它不知道 ArkTS 的 UI 框架是声明式 + 装饰器的复合体。它把 ArkTS 当成普通的 TypeScript 在写,语法上过得去,运行时就崩。
二、我手写的对照版本
typescript
// 手写版
@Component
struct WaterfallCard {
@State @Watch('onItemChange') item: CardItem = new CardItem()
private dataSource: CardItem[] = []
onItemChange() {
// 触发图片高清请求
}
@Builder
private itemCard(item: CardItem) {
Column() {
Text(item.title)
Image(item.cover)
}
}
build() {
List({ space: 10 }) {
ForEach(
this.dataSource,
(item: CardItem) => item.id.toString(), // 显式 key
(item: CardItem) => {
ListItem() {
this.itemCard(item) // Builder 调用,但参数是 item
}
}
)
}
}
}
区别一眼就能看出来:关键差异不在「能不能写出来」,在「为什么这么写」 。AI 没有项目上下文,不知道 onItemChange 要请求高清图,不知道 key 缺失会丢状态。
你要是把 AI 的版本直接复制粘贴进项目,跑起来没崩算你运气好。
三、为什么 ArkTS 这么特殊?训练数据少
我去 Hugging Face 搜过,开源鸿蒙 ArkTS 代码仓库数量大约是 React 的 1/200,TypeScript 的 1/500。AI 学都没学过几个,怎么写得对?
更麻烦的是,ArkTS 是个装饰器 + 状态 + 渲染三件套强耦合 的语言。@State、@Prop、@Link、@Builder、@Extend、@Styles 这些装饰器互相之间的组合规则,文档里有,但代码示例不够。AI 写错不是它笨,是真没见过几个对的例子。
这也解释了为什么 Vue、React 的 AI 生成质量高很多------这几个框架的代码在 GitHub 上是海量。
四、AI 真正擅长的是这三件事
说了这么多 AI 不行的,但 AI 在雷达鸭项目里我天天用,主要在三个地方:
1. 写 JSDoc 注释
typescript
/**
* AI 生成的注释(30 秒)
* @param id 案例唯一标识
* @returns 案例详情对象,未找到时返回 null
*/
async function fetchCaseDetail(id: string): Promise<CaseDetail | null> { ... }
这种纯模板化的注释 AI 写得又快又准。我手写要 1 分钟,AI 30 秒。
2. 写单测模板
typescript
// AI 生成的单测骨架
describe('fetchCaseDetail', () => {
it('should return detail when id exists', async () => {
const result = await fetchCaseDetail('valid_id')
expect(result).toMatchObject({ id: 'valid_id' })
})
it('should return null when id not found', async () => {
const result = await fetchCaseDetail('invalid')
expect(result).toBeNull()
})
})
骨架给出来后,我再补充业务断言。这比自己从零写快 3 倍。
3. 写样板路由/配置
比如 router 的批量注册、.hvigorfile.ts 的 build 脚本、.app.json 的页面声明------这种纯字符串拼接的活,AI 是碾压式的。
五、我现在的 AI 协作三区法则
我把自己写代码的状态分了三类:
| 区域 | AI 接管度 | 典型工作 |
|---|---|---|
| 绿区(机械活) | 100% | 注释、单测骨架、配置、批量重命名 |
| 黄区(套路活) | 50% | 工具函数、数据转换、简单列表渲染 |
| 红区(决策活) | 0% | 状态管理、动画、复杂 UI、API 设计 |
绿区 AI 全权代理,黄区我写框架 AI 补细节,红区 AI 闭嘴我自己来。
三个月下来,绿黄红的工作量占比大约是 4:4:2。AI 看似只干了 40% 的活,但这 40% 是最不费脑的------相当于把每天 2 小时的重复劳动外包出去。
六、最后给你一个判断标准
下次你让 AI 写 ArkTS 代码,先问自己一个问题:
这段代码,AI 如果写错了,我能在 5 分钟内看出来吗?
能看出来,交给 AI。看不出来,自己撸。
核心 UI 组件的 bug 我可能要调半天,这种活绝不让 AI 碰。但工具函数、注释、单测------错了也不致命,AI 写得快就让它写。
这是我从三个月真实项目里总结出来的判断标准,没有银弹,但能让你少踩 80% 的坑。
你用 AI 写 ArkTS 时翻过车吗?是哪类代码?留言聊聊。
关于作者:十年以上软件开发老兵,软件设计师 + 注册人工智能工程师 + agent 工程师,主要写鸿蒙 ArkTS 北向开发和 Web 前端,最近在折腾 AI 自动化提效。不定期在 CSDN 分享一些鸿蒙 / AI 方向的实战笔记。
本文遵循 MIT 协议,转载请注明出处。