DevEco Code vs Cursor:谁才是ArkTS王者
2026/6/18 15:01:19 网站建设 项目流程

DevEco Code vs Cursor:谁才是ArkTS王者


先甩结论:DevEco Code、Cursor、GitHub Copilot 三款 AI 工具写鸿蒙代码,我只留了一个。被踢掉的那个,你可能猜不到。

HDC2026 刚结束不到一周,华为发布了 DevEco Code 和 DevEco CLI。定位很清楚——"懂鸿蒙"的 AI 编程助手。你说我一个用 Cursor 写了大半年 ArkTS 的人,能不心动吗?

测试需求:一个下拉刷新列表页

选这个场景是有原因的。ArkTS 里Refresh组件和List组件的组合写法,是 AI 工具最容易出现"看着对但跑不起来"的重灾区。你要是写过鸿蒙,肯定知道这个组合有多坑——API 12 之前和之后写法还不一样。

三款工具用的同一个 prompt:

用 ArkTS 写一个下拉刷新列表页,使用 Refresh + List 组件, 支持下拉刷新数据(模拟 2 秒延迟)和上拉加载更多。 数据项包含 title 和 subtitle 两个字段,展示为卡片样式。

Copilot:第一个出局的

GitHub Copilot 给我的第一版代码长这样:

@Entry@Componentstruct RefreshList{@Stateitems:string[]=[]@Staterefreshing:boolean=falsebuild(){Refresh({refreshing:$$this.refreshing}){List(){ForEach(this.items,(item:string)=>{ListItem(){Text(item)}})}}.onRefresh(()=>{this.loadData()})}}

$$this.refreshing?ArkTS 里压根没这个语法。这明显是 React 双向绑定的思路硬搬过来的。而且Refresh组件在 API 12+ 里的用法根本不是这样的——refreshing参数从构造函数里移出去了,改成属性方法。

等一下,这里我漏说一个前提。我文件后缀是.ets,理论上 Copilot 应该能从上下文推断出这是鸿蒙代码。但显然,它的训练数据里 ArkTS 的样本少得可怜。

我又试了两轮——加了"HarmonyOS ArkTS"关键词、把官方文档示例贴进上下文——Copilot 依然在用 React 的思路写鸿蒙。第三次翻车后我直接关了,不再浪费时间。

DevEco Code:语法没毛病,就是太能写了

DevEco Code 生成的代码,语法层面确实比 Copilot 靠谱很多:

interfaceItemData{title:stringsubtitle:string}constmockData:ItemData[]=Array.from({length:30},(_,i)=>({title:`标题${i+1}`,subtitle:`这是第${i+1}条数据的描述信息`}))@Entry@Componentstruct RefreshList{@StateisRefreshing:boolean=false@StateisLoadingMore:boolean=false@Stateitems:Array<ItemData>=[]@StatepageIndex:number=1@StatehasMore:boolean=true@StaterefreshStatus:RefreshStatus=RefreshStatus.Idle@StatelastRefreshTime:string=''@StateerrorMessage:string=''@StateretryCount:number=0aboutToAppear(){this.loadData()}asyncloadData(){this.isRefreshing=truetry{awaitnewPromise<void>((resolve)=>setTimeout(resolve,2000))this.items=mockData.slice(0,10)this.pageIndex=1this.hasMore=true}catch(error){this.errorMessage='加载失败'}finally{this.isRefreshing=false}}asyncloadMore(){if(this.isLoadingMore||!this.hasMore)returnthis.isLoadingMore=truetry{awaitnewPromise<void>((resolve)=>setTimeout(resolve,1000))conststart=this.items.lengthconstnewData=mockData.slice(start,start+10)this.items=[...this.items,...newData]this.pageIndex++if(newData.length<10){this.hasMore=false}}catch(error){this.errorMessage='加载更多失败'}finally{this.isLoadingMore=false}}build(){Column(){Refresh(){List({space:12}){ForEach(this.items,(item:ItemData)=>{ListItem(){Column(){Text(item.title).fontSize(16).fontWeight(FontWeight.Bold)Text(item.subtitle).fontSize(14).fontColor('#666666').margin({top:4})}.padding(16).backgroundColor('#FFFFFF').borderRadius(8).width('100%')}},(item:ItemData)=>item.title)}.width('100%').layoutWeight(1)}.refreshing(this.isRefreshing).onRefresh(()=>{this.loadData()})}.width('100%').height('100%')}}

你看出来了吧?接近 100 行代码,功能齐全,编译也能过。但我只要一个下拉刷新列表页,它给我整了一套错误处理 + 重试机制 + 分页状态管理。retryCountlastRefreshTimeerrorMessage?我一个都没让它写。

说白了,DevEco Code 的毛病跟大部分"懂框架"的 AI 工具一样——它觉得给你写得越多越负责。但你只是想快速出个原型,200 行模板代码反而增加阅读成本。

我砍掉多余的状态和逻辑,只留核心功能,大概 45 行:

interfaceItemData{title:stringsubtitle:string}constmockData:ItemData[]=Array.from({length:30},(_,i)=>({title:`标题${i+1}`,subtitle:`这是第${i+1}条数据的描述信息`}))@Entry@Componentstruct RefreshList{@StateisRefreshing:boolean=false@StateisLoadingMore:boolean=false@Stateitems:Array<ItemData>=[]@StatehasMore:boolean=trueaboutToAppear(){this.items=mockData.slice(0,10)}build(){Refresh(){List({space:12}){ForEach(this.items,(item:ItemData)=>{ListItem(){Column(){Text(item.title).fontSize(16).fontWeight(FontWeight.Bold)Text(item.subtitle).fontSize(14).fontColor('#666666').margin({top:4})}.padding(16).backgroundColor('#FFFFFF').borderRadius(8).width('100%')}},(item:ItemData)=>item.title)}.width('100%').layoutWeight(1)}.refreshing(this.isRefreshing).onRefresh(()=>{this.isRefreshing=truesetTimeout(()=>{this.items=mockData.slice(0,10)this.hasMore=truethis.isRefreshing=false},2000)}).width('100%').height('100%')}}

等一下——精简版里我漏了上拉加载。算了,不加了,这篇文章的重点不是教你怎么写完整列表页,是对比 AI 工具。上拉加载逻辑你照着下拉刷新的思路自己加就行。

Cursor:偶尔幻觉,但改起来最快

Cursor 的第一版代码比 Copilot 靠谱,但比 DevEco Code 轻量。它踩的坑是另一个方向——API 版本混淆。

它给我生成的Refresh组件写法是这样的:

Refresh({refreshing:this.isRefreshing}){List(){// ...}}.onRefresh(()=>{this.loadData()})

如果你在 API 11 及以下版本,这种构造函数传参的写法是对的。但 API 12 改成了属性方法.refreshing(),构造函数里不再接受refreshing参数。Cursor 的训练数据里两种写法都有,它随机挑了一个——恰好挑了个旧的。

但我选 Cursor 的理由很简单:你告诉它一次,它第二次就改对了。不像 DevEco Code,你让它删掉retryCount,它改了,但errorMessage的引用还留着,你得再改一轮。代码越冗余,迭代成本越高。

我手头在做的一个 App 叫雷达鸭,它的分类列表页就是用 Cursor 写的初版,然后我手动改了RefreshList的嵌套方式。从开写到编译通过大概 40 分钟,Cursor 帮我省了至少 20 分钟的模板代码。

我留了哪个?

Cursor。但它不是万能的。

如果你的情况是"我完全不懂 ArkTS,想靠 AI 全自动生成",那目前三款工具都不够格。DevEco Code 最接近"能跑",但你得花时间砍掉过度生成的部分。

如果你对 ArkTS 有基本了解,只是想让 AI 帮你省掉写模板代码的时间,Cursor 目前迭代效率最高——前提是你得随时盯着它的 API 版本。

至于 DevEco Code,它有一个场景确实比 Cursor 强:你需要查鸿蒙某个组件的最新用法时。毕竟它是专门喂了鸿蒙文档的。写代码?还在努力。查文档?比谁都快。

你平时用哪款 AI 写鸿蒙代码?有没有踩过类似的坑?


关于作者:老三,10+ 年软件开发老兵,软件设计师,注册人工智能工程师,agent 工程师。专注鸿蒙 ArkTS 北向开发和 Web 前端,偶尔折腾 AI 自动化,不定期在 CSDN 分享技术文章。

本文遵循 MIT 协议,转载请注明出处。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询