1. 从零搭建HarmonyOS开发环境
第一次接触HarmonyOS开发时,我花了两天时间才把环境搭好。现在回想起来,如果当时有人告诉我这些避坑技巧,至少能节省半天时间。这里分享我的环境配置清单:
- DevEco Studio 3.1+:建议直接从官网下载最新版,旧版会遇到各种奇怪的兼容性问题
- Node.js 16.x:ArkUI编译依赖Node环境,版本过高或过低都会导致构建失败
- Java SDK 11:HarmonyOS的编译工具链基于Java 11开发
- 真机设备:虽然模拟器能用,但真机调试体验更流畅(我用的是华为MatePad)
安装完DevEco Studio后,记得在SDK Manager中勾选:
- JS/eTS SDK(根据开发语言选择)
- Toolchains中的Previewer和HVD Manager
- 对应API版本的System-image
注意:国内开发者建议配置华为镜像源,否则Gradle同步可能卡住。在gradle.properties中添加:
systemProp.http.proxyHost=mirrors.huaweicloud.com systemProp.http.proxyPort=80 systemProp.https.proxyHost=mirrors.huaweicloud.com systemProp.https.proxyPort=80
2. 创建购物车项目结构
新建项目时选择"Empty Ability"模板,语言选eTS(ArkUI的主力开发语言)。我习惯这样组织代码结构:
resources/ ├── base/ │ ├── element/ # 字符串资源 │ ├── media/ # 图片资源 │ └── profile/ # 样式文件 src/main/ ├── ets/ │ ├── components/ # 公共组件 │ ├── model/ # 数据模型 │ ├── pages/ # 页面入口 │ └── utils/ # 工具类 └── resources/ # 模块级资源关键配置技巧:
- 在config.json中声明页面路由时,路径不要带.ets后缀
- 图片资源建议使用
$r('app.media.xxx')方式引用 - 多设备适配可以在resources下创建不同尺寸的限定词目录(如
resources/tablet)
3. 商品列表页开发实战
商品列表是购物车的入口,我采用Tabs+List的经典布局。先看核心代码结构:
@Component struct GoodsItem { @Prop goods: GoodsData build() { Row() { Image(this.goods.image) .width(120) .aspectRatio(1) Column() { Text(this.goods.title) .fontSize(16) .maxLines(1) Text(`¥${this.goods.price}`) .fontColor('#FF4500') } } .padding(10) } } @Entry @Component struct GoodsList { @State goodsData: GoodsData[] = [] aboutToAppear() { this.goodsData = fetchGoods() // 模拟数据请求 } build() { List({ space: 10 }) { ForEach(this.goodsData, item => { ListItem() { GoodsItem({ goods: item }) } }) } .onScrollIndex((start, end) => { // 滚动到底部加载更多 if (end >= this.goodsData.length - 5) { loadMoreGoods() } }) } }性能优化点:
- 给List设置固定宽高避免重复计算
- 使用ForEach的第二个参数指定唯一键
- 复杂Item建议使用@Reusable装饰器
- 图片加载添加placeholder
4. 购物车功能深度实现
购物车的难点在于状态管理,我采用ArkUI的@Provide/@Consume机制实现跨组件通信:
// 购物车Store class CartStore { @Provide total: number = 0 @Provide items: GoodsData[] = [] addItem(item: GoodsData) { this.items.push(item) this.total += item.price } } // 商品项组件 @Component struct AddToCart { @Consume cart: CartStore @Prop goods: GoodsData build() { Button('加入购物车') .onClick(() => { this.cart.addItem(this.goods) prompt.showToast({ message: '添加成功' }) }) } } // 购物车页面 @Entry @Component struct ShoppingCart { @Provide cart: CartStore = new CartStore() build() { Column() { List({ space: 5 }) { ForEach(this.cart.items, item => { ListItem() { CartItem({ goods: item }) } }) } .layoutWeight(1) Text(`合计:¥${this.cart.total}`) .fontSize(18) .margin(10) } } }踩坑记录:
- @Provide/@Consume对嵌套对象监听不敏感,需要手动触发更新
- 大量数据操作建议放在worker线程
- 购物车数据建议持久化到Storage
5. 商品详情页开发技巧
详情页需要处理多种交互:
- 图片轮播
- 规格选择
- 加入购物车动画
图片轮播我推荐使用Swiper组件:
Swiper({ index: 0, autoPlay: true, interval: 3000 }) { ForEach(this.goods.images, img => { Image(img) .objectFit(ImageFit.Contain) }) } .indicator(true)实现加入购物车动画时,可以用显式动画配合绝对定位:
@State scale: number = 1 @State opacity: number = 1 @State translateY: number = 0 Button('加入购物车') .onClick(() => { animateTo({ duration: 500, curve: Curve.EaseOut }, () => { this.scale = 0.5 this.opacity = 0 this.translateY = -100 }) // 动画结束后重置状态 setTimeout(() => { this.scale = 1 this.opacity = 1 this.translateY = 0 }, 500) }) .scale({ x: this.scale, y: this.scale }) .opacity(this.opacity) .translate({ y: this.translateY })6. 项目调试与优化心得
开发完成后,我用DevEco Studio的调试工具做了这些优化:
性能分析:
- 使用HiProf查看渲染耗时
- 检查List的FPS是否稳定在60帧
- 分析内存泄漏点
多设备适配:
@Styles function tabletStyle() { .width('80%') .height('60%') } @Component struct ResponsiveComponent { @StorageProp('deviceType') device: string = 'phone' build() { Column() { if (this.device === 'tablet') { Text('平板布局').tabletStyle() } else { Text('手机布局') } } } }常见问题解决:
- 图片加载慢:启用内存缓存
Image($r('app.media.product')) .cacheStrategy(CacheStrategy.Storage)- 列表卡顿:启用懒加载
List({ scroller: this.scroller }) { // ... } .cachedCount(5) // 预加载数量
最后打包时,记得在build-profile.json中配置多hap打包策略,适配不同设备类型。