Harmony案例分析(1)——美团购物
任务背景
任务描述
根据接口数据和美团APP,仿照美团购物界面进行开发,构建商品与购物车之间的逻辑关系
训练目标
理解UI刷新原理
掌握组件间传值方法,如@Prop、@Link、@Provide与@Consume
掌握持久化方法
实现思路
布局
用Coloumn、Row进行布局,通过onClick和if-else触发或切换组件
传值
将商品写成对象数组通过@Link传递
商品数量令用一个number数组存储到AppStorage上
问题与解决方案
问题
解决方案
加入商品数组的会有重复
写一个面对对象数组的去重函数
优化
待优化方向
对商品数组和商品数量数组做持久化
具体优化思路
参考答案分析
总结
有点麻烦,但没啥难度。收获不少,如下:
对象数组的去重
dedupe() { let newCart:Foods[] = [] this.shoppingCartArr.forEach((item:Foods)=>{ return newCart.includes(item)?'':newC ...
Harmony小技巧(2)——组件
使用开源组件
//安装ohpm install lite_chart//引用import { LiteChart } from 'lite_chart'
组件
aspectRatio(m/n)
m/n为宽高比
布局调整
layoutWeight(n)
n为占据的份额。可用于底部,这样底部上方的内容不会把底部挤掉
.margin({})
.padding({})
stateStyles
里面只能使用通用属性
.stateStyles({ normal:{ .width(130) .height(130) }, pressed:{ .width((180)) .height(180) }, disabled:{ .backgroundColor(Color.Green) }, selected:{ .width(280) .height(280) }, focused :{ .width(280) .height(280) & ...
Harmony国际化
配置路径
resources/base/element/string.json
resources/zh-CN/element/string.jsonresources/base/
添加条目
{ "name": "module_desc", "value": "module description"},
使用
Text($r("app.string.calculator"))
Harmony性能优化
懒加载
使用LazyForEach而不是ForEach。
LazyForEach(this.data, (item: string) => { ListItem() { Row() { Text(item).fontSize(20).margin({ left: 10 }) } }.onClick(() => { this.data.pushData('item value: ' + this.data.totalCount()) }) }, item => item)
Harmony通用信息(2)——通用事件
通用事件
点击
//distanceThreshold参数作为点击事件移动阈值,当手指的移动距离超出所设置的点击手势移动阈值时,点击手势识别失败//distanceThreshold默认值:2^31-1onClick(event: Callback<ClickEvent>, distanceThreshold: number): T
触摸
//当手指在组件上按下、滑动、抬起时触发。onTouch(event: (event: TouchEvent) => void): T//该接口只能在TouchEvent中调用//通过该接口获取触发onTouch时当前帧历史点的相关信息。//onTouch一帧只会调用一次,若当前帧收到的TouchEvent大于1,会将该帧最后一个点通过onTouch返还,剩余点作为历史点getHistoricalPoints(): Array<HistoricalPoint>
挂载卸载
组件从组件树上挂载、卸载时触发的事件。
//组件挂载至组件树时触发此回调。//回调的调用时机一定在组件布局渲染之前//不允许在回调中对组件树进行变更// ...
Harmony常用组件(2)——其他
其他
遍历组件
ForEach(this.list,(item:Type,idx)={ myComponent({myVal:item}) })struct myComponet{ myVal:TYPE}
Button
Button('sss') .enabled(this.isSelect)
Checkbox
Checkbox() .select($$this.isSelect)
Refresh
下拉刷新
Refresh({ refreshing:$$this.isRefresh, builder:this.Refresh()}){}.onRefreshing(()=>{ setTimeout(()=>{ this.changeRefreshLoading() AlertDialog.show({message:'ok'}) },20 ...
Harmony路由
Harmony路由原理
一个Ability里面的多个page可通过router进行切换。
页面内
页面内跳转是指所跳转的页面在同一个Ability内部,它们之间的跳转可以使用Router或者Navigator的方式
页面间
页面间跳转是指所跳转的页面属与不同的Ability,这种跳转需要借助featureAbility(featureAbility模块的startAbility()方法)实现
featureAbility有如下方法:
declare namespace featureAbility { /**省略部分方法*/ //打开指定 Ability 。默认第一个 function startAbility(parameter: StartAbilityParameter, callback: AsyncCallback<number>): void; function startAbility(parameter: StartAbilityParameter): Promise<number>; function startAbilit ...
Harmony基本原理(3)——生命周期
组件
组件是 OpenHarmony 页面最小显示单元
为了让系统知道这是一个组件,需要使用 @Component 修饰符和 struct 关键字修饰
自定义组件禁止添加构造函数
必须实现 build()方法,该方法满足 Builder 构造器接口定义,用于定义组件的声明式 UI 描述
在组件创建或者组件内 @State 修饰的变量更新时系统都会自动调用 build() 方法刷新UI
系统组件生命周期
onAppear()onDisAppear()
自定义组件生命周期
@Component 修饰的组件,ArkUI开发框架会自动为其赋予私有的生命周期方法 aboutToAppear() 和 aboutToDisappear() ,它们用于通知开发者该自定义组件的生命周的变更
//函数在创建自定义组件的新实例后,在执行其 build() 函数之前执行//允许在该函数中改变状态变量,更改将在后续执行 build() 函数中生效aboutToAppear()//函数在自定义组件析构消耗之前执行//不允许在该函数中改变状态变量,特别是 @Link 变量的修改可能会导致应用程序行为不稳定abo ...
Harmony媒体相关
媒体组件
Video
controller:VideoController=new VideoController()Video({src:'',currentProgressRate:this.speed,controller:this.controller}) .controls(false) .onPrepared((value)=>{ if (this.currentPlayIndex==this.currentIndex){ this.controller.start() } })//使用this.controller.start()this.controller.pause()