Harmony应用开发学习笔记

208 阅读5分钟

前言

在线JSON转TypeScript接口工具 - 类型定义生成

文档中心-HarmonyOS NEXT开发文档-华为开发者联盟

华为开发者文章 | 华为开发者联盟

华为开发者鸿蒙专区小助手_-CSDN博客

一. 基本语法概述

1. @Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,状态变量变化会触发UI刷新,而struct 不是装饰器,是关键字,用来定义组件

image.png

2.页面和自定义组件生命周期

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • onPageShow:页面每次显示时触发。
  • onPageHide:页面每次隐藏时触发一次。
  • aboutToDisappear:在自定义组件即将析构销毁时执行。
  • onBackPress:当用户点击返回按钮时触发。

image.png (1).A页面初次加载---aboutToApper()--->build()--->onPageShow() (2).A页面跳转到B页面---B.aboutToApper()--->B.build()--->A.onPageHide()--->B.onPageShow() (2).B页面按返回键到A页面---B.onBackPress()--->B.onPageHide()--->A.onPageShow--->B.aboutToDisapper()

3.@Builder装饰器:自定义构建函数

  • 组件内自定义构建函数(无function声明) @Builder MyBuilderFunction(){ ... } 使用方法:this.MyBuilderFunction(){ ... }

  • 全局自定义构建函数(有function声明) @Builder function MyGlobalBuilderFunction(){ ... } 使用方法:MyGlobalBuilderFunction()

4.@BuilderParam装饰器:引用@Builder函数

  • 初始化@BuilderParam装饰的方法 注意:@BuilderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化。
@Component
struct Child {
  @BuilderParam aBuilder0: () => void = this.doNothingBuilder
  build(){}
}
  • 用父组件自定义构建函数初始化子组件@BuilderParam装饰的方法
@Component
struct Child {
  @BuilderParam aBuilder0: () => void;

  build() {
    Column() {
      this.aBuilder0()
    }
  }
}

5.鸿蒙中使用interface - 定义纯数据类型(而不是使用java的Class类)

// interface - 纯数据类型定义(推荐)
export interface BannerDataModelData {
  desc: string;
  id: number;
  imagePath: string;
  isVisible: number;
  order: number;
  title: string;
  type: number;
  url: string;
}

// class - 包含逻辑(不推荐用于纯数据)
export class BannerDataModelData {
  desc: string;
  id: number;
  // ...其他字段
  
  // 可能包含不必要的方法
  validate(): boolean {
    return this.id > 0;
  }
}

6.ArkTS中单例模式的优雅实现方式.(特别适合管理应用级的配置数据和共享状态)

  • let mainViewModel = new MainViewModel();

  • export default mainViewModel as MainViewModel;

// 这种写法的核心优势:
// ArkTS的这种写法优势:
// 更简洁:不需要私有构造函数和getInstance方法
// 模块化:利用ES6模块系统的单例特性
// 自动初始化:在模块加载时自动创建实例
//
// ✅ 简单高效:利用模块系统天然的单例特性
// ✅ 性能优化:避免重复创建相同的配置数据
// ✅ 维护性:集中管理tab配置,一处修改全局生效
// ✅ HarmonyOS最佳实践:符合官方推荐的数据共享模式
export class MainViewModel {
  /**
   * 首页底部Tab显示数据
   */
  tabTitle: Array<TabItem> = [
    {
      index: 0,
      title: "首页",
      imageActivated: $r('app.media.icon_sel_home'),
      imageOriginal: $r('app.media.icon_unsel_home')
    },
    {
      index: 1,
      title: "发现",
      imageActivated: $r('app.media.icon_sel_find'),
      imageOriginal: $r('app.media.icon_unsel_find')
    },
    {
      index: 2,
      title: "热门",
      imageActivated: $r('app.media.icon_sel_hot'),
      imageOriginal: $r('app.media.icon_unsel_hot')
    },
    {
      index: 3,
      title: "我的",
      imageActivated: $r('app.media.icon_sel_mine'),
      imageOriginal: $r('app.media.icon_unsel_mine')
    }
  ]
}

let mainViewModel = new MainViewModel();

export default mainViewModel as MainViewModel;

7.使用vp自适应间距,使用fp自适应字体.

    Column() {

      Image(item.index ==index? item.imageActivated:item.imageOriginal)
        .width("21vp").height("21vp")

      Text(item.title).fontSize("10fp")
        .margin("5vp")

    }
    .width("100%").height("100%")
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)

8. $$ 的作用原理

  • $$ 组件参数中使用 $$this.isRefreshing 时,ArkUI 框架会自动将 @State 变量转化为双向绑定.

9. Array= []等价于 HomeModelIssueListItemList[]=[]

10.if(showLoadingState!==false){}和if(showLoadingState){}的区别

(1).if(showLoadingState!==false)

showLoadingState!== falseif (showLoadingState)
true✅ 执行✅ 执行
false❌ 不执行❌ 不执行
undefined✅ 执行❌ 不执行
null✅ 执行❌ 不执行
0✅ 执行❌ 不执行
"" (空字符串)✅ 执行❌ 不执行
NaN✅ 执行❌ 不执行
{} (空对象)✅ 执行✅ 执行
[] (空数组)✅ 执行✅ 执行

(2).if(showLoadingState){}

showLoadingState 的值if (showLoadingState) 结果说明
true✅ 执行布尔真值
false❌ 不执行布尔假值
0❌ 不执行数字零视为假
1✅ 执行非零数字视为真
"" (空字符串)❌ 不执行空字符串视为假
"hello"✅ 执行非空字符串视为真
null❌ 不执行null 视为假
undefined❌ 不执行undefined 视为假
{} (空对象)✅ 执行任何对象(包括空对象)都视为真
[] (空数组)✅ 执行任何数组都视为真

11.!==,===和 !=,==的区别

运算符行为推荐场景
!== / ===严格相等,不转换类型推荐,尤其在判断 0falsenullundefined 等值时更安全
!= / ==宽松相等,会隐式类型转换不推荐,容易产生意料之外的结果(如 "0" == 0 为 true
let errorCode = "0";   // 字符串

if (errorCode !== 0) {
    // ✅ 会进入这里,因为 "0" !== 0 类型不同
}

if (errorCode != 0) {
    // ❌ 不会进入这里,因为 "0" == 0 会先将字符串转为数字,相等
}

12.export default useRequestStatus 或者 export { useRequestStatus };

默认导出export default useRequestStatus;import anyName from './module'
命名导出export { useRequestStatus };import { useRequestStatus } from './module'
  • 默认导出
function useRequestStatus(stateCallback?: (state: string) => void, checkResult: boolean = false): LoadStateResult {
  return {
    promise: (requestPromise, showLoadingState) => run(requestPromise, checkResult, showLoadingState, stateCallback)
  };
}

export default useRequestStatus;

  • 命名导出
function useRequestStatus(stateCallback?: (state: string) => void, checkResult: boolean = false): LoadStateResult {
  return {
    promise: (requestPromise, showLoadingState) => run(requestPromise, checkResult, showLoadingState, stateCallback)
  };
}

export { useRequestStatus} 

或者直接给function 加上 export修饰符

export function useRequestStatus(stateCallback?: (state: string) => void, checkResult: boolean = false): LoadStateResult {
  return {
    promise: (requestPromise, showLoadingState) => run(requestPromise, checkResult, showLoadingState, stateCallback)
  };
}

二.状态管理V1

  • @State装饰器 使变量拥有状态属性的装饰器
  • @Prop装饰器:装饰的变量可以和父组件建立单向的同步关系,父组件变化会自动同步到子组件,子组件对变量的修改不会自动传递到父组件。
  • @Link装饰器:父子双向同步
  • @Provide装饰器和@Consume装饰器:与后代组件双向同步(一对多关系)
  • @Watch装饰器 :为状态变量设置回调函数 (无法实现对对象、数组中某一单个属性或数组项变化的监听)
  • @Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化(解决状态失效的问题)
tip:状态管理V1存在多种可接受外部传入的装饰器:@State@Prop@Link@ObjectLink (子组件参数)

三.状态管理V2

  • @Local装饰器:组件内部状态 (无法确保@State装饰变量的初始值一定为组件内部定义的值)
  • @Param: 组件外部输入。(子组件接收参数)
  • @ObservedV2装饰器和@Trace装饰器:解决@Observed装饰器和@ObjectLink调用过于复杂的问题.
  • @Once:仅初始化同步一次。(@Once必须搭配@Param使用)
  • @Event装饰器 :规范组件输出,修饰函数
  • @Provider和@Consumer 跨组件层级双向同步
  • @Monitor装饰器: 状态变量修改监听.
  • @Computed装饰器:计算属性.(防止重复计算,为方法装饰器,仅能装饰getter方法)
  • @Type :使得类属性序列化时不丢失类型信息,便于类的反序列化。