2024年9月下旬uni-app的App平台正式拉起鸿蒙Next支持我记得很清楚因为那段时间圈子里天天有人问“uni-app什么时候能上鸿蒙”“鸿蒙Next和之前HarmonyOS有什么区别”。到10月中HBuilderX 4.36版本把鸿蒙Next打包流程跑通之后这条链路才算真正“能干活了”。我当时手头正好有个工具类的小项目想着既然以前做跨端都是用uni-app鸿蒙这波也不能掉队就顺手从0开始把整条路走了一遍新建项目、写页面、调API、云打包、装到真机、提审上架。这篇文章就是我走完整条路之后的整理尽量按一个新手实际操作的顺序来说能少踩一个坑是一个坑。如果你是那种以前只做过微信小程序、或者只写过一点Vue还没碰过鸿蒙开发的同学这篇文章很适合你。哪怕你对鸿蒙Next完全没概念只要跟着操作也能把一个能跑的真应用做出来并且提交到应用市场。如果本身就是安卓/iOS开发出身那更简单重点看第三章和第四章的适配差异就行。1. 环境准备HBuilderX和DevEco Studio怎么搭配才不白忙活先说结论做uni-app鸿蒙Next开发并不是只装一个HBuilderX就够了。HBuilderX负责写代码、编译、云打包但鸿蒙Next上架还需要鸿蒙官方的签名工具和SDK这就要装DevEco Studio。很多小白卡在第一步就是只装了一个工具然后发现云端打包脚本一堆报错。1.1 版本选择是这个环节最容易踩的坑截至我写这篇内容的时间点比较稳的版本组合是HBuilderX4.36及以上正式版别用太老的也不能用纯Alpha版碰到bug还要自己折腾。DevEco Studio5.0.0及以上主要是为了拿鸿蒙Next的SDK和签名工具链。Node.js建议20 LTSHBuilderX内置的Node有时候版本偏旧跑脚本会莫名报错。鸿蒙SDK在DevEco Studio里通过Settings - SDK Manager勾选API 12及以上的版本因为鸿蒙Next对标的就是API 12。这里提醒一句DevEco Studio下载的时候有个坑官网会提供Windows、Mac两个大版本Mac又区分Intel和Apple Silicon。如果你用的是M系列芯片一定要下arm64版本否则后面启动模拟器会卡得怀疑人生。1.2 HBuilderX里正确配置鸿蒙开发路径装好DevEco Studio之后打开HBuilderX点击菜单栏“运行” - “运行到手机或模拟器” - “运行到鸿蒙Next”第一次会让你配置DevEco Studio的安装路径。注意这里填的不是DevEco Studio的快捷方式路径而是它实际安装目录下的bin目录。举个例子Windows下如果是默认安装路径通常是C:\Program Files\Huawei\DevEco Studio\binMac下是/Applications/DevEco Studio.app/Contents/MacOS。填错的话HBuilderX会提示找不到hvigorw相关命令这个报错很长一串核心其实就一句话路径不对。配置完之后建议先跑一次“运行到鸿蒙Next模拟器”。但这里有个现实问题鸿蒙Next的模拟器体积很大而且默认只有一个手机模拟器镜像下载要几个G。如果你只是验证代码逻辑其实可以用真机。真机只需要在开发者选项里打开USB调试然后用数据线连上电脑HBuilderX如果识别不到设备大概率是缺了华为手机助手驱动去官网装一下就好。1.3 为什么要装这么多东西一次性讲清楚很多新手不理解为什么uni-app这种跨端框架还需要原生工具链。打个比方HBuilderX相当于一个翻译官把你的Vue代码翻译成鸿蒙Next能认识的底层指令但它只负责“翻译和打包”最后的“签名”和“上架”环节需要鸿蒙官方发的身份证也就是证书这个只有DevEco Studio里的工具才能生成。所以两个工具各管一段缺一不可。如果你以前做过微信小程序开发可以这样理解HBuilderX相当于微信开发者工具DevEco Studio相当于微信公众平台后台里的“开发管理”那部分一个写代码调预览一个管证书和发布。这样想一下就顺了。2. 新建uni-app项目并吃透鸿蒙Next的工程结构环境装好之后打开HBuilderX文件 - 新建 - 项目项目类型选“uni-app”。这里特别注意默认模板里有一个“默认模板”和一个“默认模板(TypeScript)”新手建议选默认模板别一上来就TypeScript因为鸿蒙Next插件的类型定义还不算特别完善报错的时候看类型定义反而更乱。2.1 manifest.json鸿蒙Next所有配置的大本营创建完项目后项目根目录下有个manifest.json千万别只把它当成小程序的配置文件。HBuilderX 4.36版本里这个文件专门多了一个“鸿蒙Next”配置块主要管三件事AppID这是DCloud平台分配的应用标识没有它云打包都打不了。在HBuilderX菜单“发行” - “制作应用证书”那一步会引导你去DCloud开发者中心注册注册完就能拿到AppID。模块配置如果你的应用要用到蓝牙、地图、相机这些原生能力必须在这里勾选对应模块否则打包出来即使代码写了调用也白搭。鸿蒙权限声明这个和手机上弹出的授权弹窗直接相关比如定位权限你需要在源码视图里找到ohos节点加一行requestPermissions声明具体写法我在第四章详细说。很多小白第一次打包成功但装到手机上功能不完整回头查基本都是manifest.json里该勾的没勾。这个文件好比是打包的“点菜单”你没点的菜后厨原生模块是不会给你做的。2.2 入口文件main.js和App.vue的分工打开项目根目录的main.js这是uni-app的Vue实例入口。鸿蒙Next环境下这里的写法和传统uni-app基本一致import App from ./App import { createSSRApp } from vue export function createApp() { const app createSSRApp(App) return { app } }这段代码的意思是鸿蒙Next的uni-app应用不是走浏览器那套直接new Vue的逻辑而是先导出一个createApp工厂函数等平台环境初始化完之后再调用来创建Vue实例。你不需要深究底层原理只需要记住不要在这里直接写app.mount(#app)之类的代码否则在鸿蒙Next上会直接白屏。App.vue里则是全局生命周期其中onLaunch会在应用启动时执行一次onShow会在应用每次从后台回到前台时执行。如果你要做全局数据初始化比如读取本地存储的登录状态应该放在onLaunch而不是onShow否则每次切后台再回来都重复执行浪费性能。2.3 pages.json路由和页面的映射表pages.json是uni-app比较核心的配置文件鸿蒙Next同样认它。里面最基础的就是pages数组第一项就是应用启动后的第一个页面。有个小坑新增页面文件后很多人忘记在这里注册结果编译不报错但运行起来点不进去或者直接白屏。所以每新建一个.vue页面都要在pages.json里加一条对应记录。同时window节点可以配置导航栏颜色、标题等。鸿蒙Next的导航栏默认样式和安卓、iOS都不太一样它更接近鸿蒙原生的“顶部标题区”风格。如果你想完全自定义导航栏把navigationStyle设为custom然后自己写页面顶部组件但要注意这时候需要手动处理状态栏高度后面第四章会提到安全区适配。3. 页面开发Vue3语法在鸿蒙Next上到底能不能放心用去年大家问得最多的一个问题就是鸿蒙Next上能用Vue3的响应式API吗答案是能而且用起来比想象中顺。但有些细节确实不一样不看文档容易踩坑。3.1 ref不是“万能对象”千万别滥用热词里有一条叫“vue3 ref万能对象”这个说法其实有误导性。ref确实是Vue3里最常用的响应式API但在鸿蒙Next环境里ref包装的是一个值而不是任意对象。看这段代码script setup import { ref } from vue const count ref(0) function add() { count.value } /script template view text{{ count }}/text button clickadd增加/button /view /template这段代码在鸿蒙Next上可以正常运行。注意两点第一模板里直接写count不需要写count.valueVue模板编译器会自动解包第二如果你想用一个响应式的对象比如表单数据用reactive更合适script setup import { reactive } from vue const form reactive({ title: , done: false }) /script为什么不建议什么都用ref因为ref在底层会做一层包装访问时还有.value这个额外的读取开销在列表很长、渲染频率高的场景下能明显感觉到卡顿。用reactive处理对象用ref处理基本类型这才是性能和语义都正确的做法。3.2 生命周期函数哪些能用、哪些不能用uni-app在鸿蒙Next上支持的生命周期大致是onLaunch / onShow / onHide应用级生命周期写在App.vue里onLoad / onReady / onShow / onHide / onUnload页面级生命周期写在页面.vue的setup里通过dcloudio/uni-app导入具体写法script setup import { onLoad, onShow } from dcloudio/uni-app onLoad((query) { console.log(页面参数, query) }) onShow(() { console.log(页面每次显示都会执行) }) /script这里有一个容易忽略的点onLoad的参数query是上一个页面跳转时带的参数。如果你用uni.navigateTo({ url: /pages/detail/detail?id123 })跳转在onLoad里就能拿到{ id: 123 }。注意它一定是字符串类型即使你传的时候是数字。至于onMounted这种Vue原生生命周期在鸿蒙Next上也能用但建议优先用uni-app封装的onLoad这类。因为onLoad是uni-app根据各平台编译结果统一处理过的行为一致而Vue的onMounted在不同平台的执行时机有细微差异写多了容易出玄学bug。3.3 Watch和计算属性都没问题但别忽略中文注释的编码坑很多开发者喜欢在代码里写中文注释这本身没问题但如果你在鸿蒙Next真机运行时报了一堆奇怪的编译错误检查一下项目文件编码是不是UTF-8。有些Windows下默认新建的文件是GBK编码HBuilderX在编译的时候会以UTF-8读取中文注释就变成了乱码轻则警告重则直接编译不过。处理办法在HBuilderX左下角状态栏能看到当前文件的编码格式统一改成UTF-8。因为鸿蒙Next SDK对文件编码要求比较严格就算编译过了乱码注释也可能在生成的原生代码里留下奇怪的字符导致运行时报错。3.4 状态管理Pinia在鸿蒙Next上怎么接入如果你的应用稍微复杂一点比如多个页面共享登录状态、购物车数据那就要用Pinia。在uni-app里接入Pinia很简单项目根目录执行npm install pinia然后在main.js里import App from ./App import { createSSRApp } from vue import * as Pinia from pinia export function createApp() { const app createSSRApp(App) const store Pinia.createPinia() app.use(store) return { app } }之后在任意页面script setup import { useUserStore } from /stores/user const userStore useUserStore() /script这里提醒一下useUserStore()必须在setup里调用不能在普通函数里调用否则Pinia还没挂载到当前组件实例会直接报getActivePinia was called with no active Pinia。很多小白在事件回调里写useUserStore()就崩了就是这个原因。4. 鸿蒙Next适配实战从尺寸单位到安全区一个都不能漏跨端开发最怕的就是“在自己电脑上好好的一到真机就变形”。鸿蒙Next在这方面有几个和微信小程序、安卓差异很明显的地方我一个个说。4.1 rpx在鸿蒙Next上的换算逻辑rpx是uni-app的响应式尺寸单位在微信小程序里规定屏幕宽度为750rpx。在鸿蒙Next上这个规则同样适用但实际渲染时会根据鸿蒙的字体缩放和屏幕密度做换算。实际体感是同一个页面同样的rpx值在鸿蒙Next真机上显示的字号比微信小程序略小一点因为鸿蒙的默认字体缩放比安卓保守。所以我的建议是文字字号不要用rpx直接用px。正文用15px标题用20px这样在鸿蒙Next上显示最稳定。rpx可以继续用在边距、宽度、高度这些布局属性上毕竟它做的是等比缩放布局错位风险小。4.2 状态栏和安全区刘海屏、挖孔屏怎么处理鸿蒙Next手机顶部状态栏的高度和安卓不一样你可以用uni.getSystemInfoSync()里的statusBarHeight拿到具体数值。但这里有个细节鸿蒙Next上状态栏高度在页面还没完全渲染好之前拿到的值可能不准确建议放在onReady里再取。如果你自定义了导航栏页面顶部组件要有内边距避免内容被状态栏和挖孔区域遮挡script setup import { onReady } from dcloudio/uni-app import { ref } from vue const statusBarHeight ref(20) onReady(() { const info uni.getSystemInfoSync() statusBarHeight.value info.statusBarHeight || 20 }) /script template view classpage-container :style{ paddingTop: statusBarHeight px } !-- 页面内容 -- /view /template底部同样要注意如果页面用了自定义底部操作按钮要避开通话导航条区域。鸿蒙Next的侧滑返回手势是系统级的你的页面如果右边沿有可点击元素可能会和手势冲突。解决办法是重要的按钮不要放在屏幕最右侧边缘或者在使用swiper组件时小心左右滑动的手势冲突。4.3 权限申请为什么明明写了代码却不弹窗鸿蒙Next的权限模型和安卓没有本质区别但uni-app的API封装度比安卓原生要高有些权限需要先在manifest.json里声明然后代码里才能触发系统弹窗。以定位权限为例在manifest.json的源码视图里找到鸿蒙Next相关节点加入{ ohos: { requestPermissions: [ { name: ohos.permission.LOCATION } ] } }然后代码里调用uni.getLocation({ type: gcj02, success(res) { console.log(定位结果, res.latitude, res.longitude) } })记住权限声明和API调用缺一不可。声明了没调用不会弹窗调用了没声明直接在API层面就被拦截而且控制台不一定会打出明显报错看起来像是什么都没发生。这是我之前浪费了两个小时排查出来的问题。4.4 深色模式适配鸿蒙Next从底层就支持深色模式而且是跟随系统自动切换。uni-app的pages.json里可以配置页面背景色但如果你想精细适配深色模式建议使用CSS媒体查询.page { background-color: #ffffff; color: #333333; } media (prefers-color-scheme: dark) { .page { background-color: #1c1c1e; color: #eeeeee; } }实测鸿蒙Next上这段媒体查询是生效的。如果你不写深色适配应用在深色模式下的默认表现会有点尴尬——背景是白色的但页面部分原生组件比如button会变成深色割裂感很明显。所以个人建议就算不精细适配至少把页面背景色在深色模式下改成深色保证基本观感。5. 真机运行与云打包从“能跑”到“有安装包”这一段是整个流程里最容易让新手失去耐心的。明明在模拟器上跑得好好的一到真机或者打包就各种报错。5.1 真机调试数据线之外还有一个隐藏步骤鸿蒙Next的真机调试比安卓多了一个环节首次连接需要在手机上开启“开发者模式”然后在“开发者选项”里打开“USB调试”和“仅充电模式下允许ADB调试”。注意如果你没有登录华为账号部分机型会锁住“仅充电模式下允许ADB调试”这个选项。连接后HBuilderX如果识别到设备控制台会打印设备型号和系统版本。识别不到的话先检查数据线——很多数据线只能充电不能传数据换一根试试。还是不行就在命令行输入adb devices如果列表是空的再看设备管理器里有没有出现未安装驱动的设备。华为手机助手装上之后基本都能解决。5.2 云打包为什么能懒就懒鸿蒙Next的打包和安卓、iOS一样也可以选本地打包和云打包。对于小白来说我强烈建议用云打包原因有三本地打包需要配置DevEco Studio完整的签名流程涉及生成.csr、.p12、.p7b、.cer四类文件光看指引就能绕晕。云打包只需要在HBuilderX里点“发行” - “原生App-云打包”勾选鸿蒙Next然后登录DCloud账号剩下的事情DCloud的服务器帮你做。即使你现在不想付费云打包也有免费额度个人开发前期完全够用。云打包前要做的准备工作在DCloud开发者中心注册账号开通开发者身份。在manifest.json里填好AppID没有AppID打包会直接失败。在HBuilderX菜单“发行” - “制作应用证书”里生成鸿蒙Next的证书文件这个证书文件会下载到本地云打包的时候选“使用自有证书”并上传。打包成功后HBuilderX会提示下载.app后缀的文件这个就是鸿蒙Next的应用安装包。注意它和我们熟悉的.apk不一样鸿蒙Next不再支持直接安装APK必须用.app格式。5.3 打包常见报错对照表报错关键字大概率原因解决思路hvigorwnot foundDevEco Studio路径配置错误检查HBuilderX里的SDK路径设置code: 2证书签名不匹配重新生成证书确保使用同一份上传appid is invalidmanifest.json里的AppID和DCloud账号不匹配去DCloud开发者中心核对ohos.permission相关模块权限声明缺失在manifest.json源码视图补充对应权限Execution failed for task本地打包时SDK版本不一致确保DevEco Studio和鸿蒙SDK都更新到API 12这里面最玄学的就是“证书签名不匹配”我遇到过好几次。后来发现是自己在打包前重新生成了证书但manifest.json里的AppID没有同步更新导致DCloud服务器拿旧AppID匹配新证书两者对不上。所以记住证书和AppID是绑定的换了一个就要检查另一个。6. 上架应用市场从签名认证到应用审核的完整链路打包成功只是完成了一大半上架才是真正让应用“见光”的环节。鸿蒙Next应用主要上架到华为应用市场也就是AppGallery Connect。6.1 上架前需要的资质文件你不需要有公司主体个人开发者也能上架鸿蒙Next应用。但以下材料必须准备开发者实名认证信息个人就是身份证手机号银行账号这一步是华为应用市场硬性要求。软件著作权证书软著。个人项目可以申请审批周期在一个月到三个月不等所以如果你准备上架软著一定要提前申请别等项目做完了才想起来。隐私政策网址。注意必须是能公开访问的HTTPS链接不能是本地文件。GitHub Pages、云开发静态托管都可以但内容要完整写明收集哪些信息、用途、存储周期等。应用图标、截图。图标要求是PNG格式至少512x512px截图至少4张建议用真机截图模拟器截图审核有时会被打回。6.2 AppGallery Connect里创建应用浏览器登录AppGallery Connect选择“应用市场” - “创建应用”。这里有个细节创建的时候需要选择“是否为鸿蒙应用”注意选“鸿蒙Next”而不是“HarmonyOS经典版”因为这是两套不同的兼容体系。创建完之后在“应用信息”里填写包名。这个包名必须和uni-app云打包时生成的包名一致否则安装包提交上去会报“包名不匹配”。如果不确定去HBuilderX的manifest.json里看appid对应生成的包名规则通常是uni.前缀加上AppID。注意这里的uni.不是固定的这个值在manifest源码视图里可以看到。6.3 提交审核从“待审核”到“已上架”上传.app安装包填写应用名称、简介、版本号然后提交审核。审核周期通常1-3个工作日实际上我最快一次当天晚上提交、第二天早上就通过了慢的也遇到过等了一周。常见的被拒原因有应用图标和名称不一致比如图标是工具类图标名称却写着游戏。必须权限申请时机不合理比如打开应用第一时间就要定位权限审核员会认为是“强关联权限收集”。隐私政策里声明的内容和应用实际行为不符。应用内没有“退出”或“注销”功能的入口这点现在审核抓得挺严。第四点值得单独说一下如果你的应用涉及用户账号系统那么在“设置”页面需要提供“注销账号”入口且注销流程必须真实可用。很多开发者忘记做这一项被打回之后才补一来一回又多了几天。6.4 版本升级uni-app的更新逻辑在鸿蒙Next上有点不一样上线之后不是终点后续肯定要发新版本。uni-app提供uni-app的判断更新API但在鸿蒙Next上最稳妥的方式是走华为应用市场的“版本更新”体系。也就是说用户在应用市场搜到你的应用时安装的是最新版本旧的版本用户打开应用市场能看到“更新”按钮。如果你要做App应用内检测更新、弹窗引导去应用市场逻辑是这样的uni.getAppBaseInfo({ success(res) { const currentVersion res.appVersionCode // 这里把 currentVersion 和服务器上的最新版本号做对比 // 如果不一致弹窗提示用户去应用市场更新 } })需要注意鸿蒙Next上appVersionCode拿到的是数字版本号而appVersionName才是“1.0.0”这种字符串版本号。判断新旧版本时优先用数字版本号因为字符串比较大小非常容易出错比如“1.10.0”会被当成比“1.9.0”小。7. 实测心得这趟鸿蒙Next移植路的几个“早知道”最后说点真心话也是我在这条路上踩完坑之后的复盘。第一个“早知道”uni-app的鸿蒙Next支持还在快速迭代期别用太“新”的写法。比如script setup里的顶层await、动态组件component :is这类比较高级的语法在鸿蒙Next上的表现不如在浏览器和小程序里稳定。能用简单语法实现的功能就别用花活。第二个“早知道”真机自测非常重要模拟器只能用来跑通逻辑。鸿蒙Next模拟器的性能还是跟不上真机尤其在渲染大量图片、长列表的时候模拟器流畅不代表真机流畅。我遇到过模拟器上滚动顺滑、真机上滑动明显掉帧的情况后来排查下来是图片列表没有做懒加载image组件的lazy-load属性没有开启。第三个“早知道”开发阶段多用真机看控制台日志。鸿蒙Next上console.log的输出在HBuilderX控制台能看到但格式和浏览器不一样它会带一些平台前缀。报错定位的时候先看error级别的日志把warn级别的先忽略否则很容易被大量无关警告带偏。第四个“早知道”先把“最小可用版本”上线再迭代功能。我当时想着一次性把所有功能做完再上架结果审核前前后后改了三个版本。后来改成先上一个只有核心功能的小版本审核通过后用户量慢慢起来再按反馈迭代反而轻松很多。鸿蒙Next目前的应用生态还在成长期审核对于新应用的包容度其实比安卓iOS要高一些早点上线比憋大招有意义得多。从0到上线这条链路现在回过头看其实并不长装环境、建项目、写页面、云打包、真机装、提审上架核心步骤就这么多。但每一步都藏着好几个“没想到”尤其是鸿蒙权限、证书匹配、审核资质这些环节文档里写得都比较分散真上手才会发现有一些坑根本没人提醒你。希望这篇内容可以帮后来的人少走几趟弯路把精力留在真正重要的业务逻辑上。