【ArkTS-装饰器】

ArkTS-装饰器

■ UI状态管理

在这里插入图片描述

■ @Entry (进入)页面的生命周期

一个页面有且仅有一个@Entry入口。

■ aboutToAppear

aboutToAppear 是一个生命周期钩子,在组件构建(build)之前、首次出现或重新出现时自动执行。
在这里插入图片描述

@Entry
@Component
struct IndexPage {
   
   
  @State userInfo: string = ''
  // 生命周期:组件即将显示时调用
  aboutToAppear() {
   
   
    console.info('IndexPage 即将显示')
    
    // 示例1:从 AppStorage 获取数据
    this.userInfo = AppStorage.get<string>('userName', '匿名用户')

    // 示例2:模拟网络请求
    this.loadUserData()

    // 示例3:埋点统计
    analyticsService.pageView('HomePage')
  }

  async loadUserData() {
   
   
    try {
   
   
      // 模拟异步请求
      const data = await fetchUserApi()
      console.info('用户数据加载完成:', data)
      // 更新状态,触发 UI 刷新
      this.userInfo = data.name
    } catch (error) {
   
   
      console.error('加载失败:', error)
    }
  }

  build() {
   
   
    Column() {
   
   
      Text(`用户:${
     
     this.userInfo}`)
        .fontSize(18)
        .margin(20)
    }
    .width('100%')
    .height('100%')
  }
}

■ aboutToDisappear

aboutToAppear() {
   
   
  console.info('页面显示')
  // 开始监听
  eventHub.on('dataUpdate', this.handleData)
}

aboutToDisappear() {
   
   
  console.info('页面隐藏')
  // 及时解绑,避免内存泄漏
  eventHub.off('dataUpdate', this.handleData)
}

■ @Component (组件)

HarmonyOS的生命周期可以分为 @Compnent的生命周期和 @Entry的生命周期 也就是自定义组件的生命周期和页面的生命周期。
@Component和@Entry,ArkTS通过这两个关键字来装饰struct声明的数据结构,这个过程我们称为自定义组件。
组件内部需要提供一个build函数,我们在该函数体内按照链式调用的方式来描述整个页面的UI布局。

■ 1. Component装饰的struct称为UI组件。主要特征:

  1. 一个页面有且仅有一个@Entry入口。
  2. 一个页面可以包含一个或多个component;
  3. 每个component都必须实现 build 方法来更新UI;
  4. 一个component内部还可以调用另外一个component;

■ 2. component内部还可以调用另外一个component 示例

示例

@Entry       //一个页面有且仅有一个@Entry入口。
@Component   //一个页面可以包含一个或多个component;
struct MainComponent {
   
   
  build() {
   
   
    Flex({
   
    direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
   
   
      Text('Black is MainComponent')
        .fontSize(26)
        .fontColor(Color.Black)
        .height(50)
      SubComponent()  //调用
			.width('100%')   //自定义组件也有属性。
			.height(200)
			.backgroundColor('#123343')
    }
    .width('100%')
    .height('100%')
  }
}

@Component  //一个页面可以包含一个或多个component;
struct SubComponent {
   
   
  build() {
   
   
    Flex({
   
    direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
   
   
      Text('Red is SubComponent')
        .fontSize(26)
        .fontWeight(500)
        .fontColor(Color.Red)
    }
    .width('100%')
  }
}

在这里插入图片描述

■ @Builder(构建): 自定义构建函数可复用 UI 片段

■ 1. @Builder无参数

  // 简单的无参数Builder
  @Builder
  simpleTextBuilder() {
   
   
    Text('Hello World')
      .fontSize(30)
      .fontWeight(FontWeight.Bold)
      .fontColor(Color.Blue)
  }

■ 2. @Builder带参数的

  // 带参数的Builder
  @Builder
  parameterizedBuilder(text: string, size: number, color: Color) {
   
   
    Text(text)
      .fontSize(size)
      .fontColor(color)
      .fontWeight(FontWeight.Medium)
  }

■ 3. @Builder包含逻辑的

  // 包含逻辑的Builder
  @Builder
  conditionalBuilder(score: number) {
   
   
    if (score >= 90) {
   
   
      Text('优秀')
        .fontColor(Color.Green)
    } else if (score >= 60) {
   
   
      Text('及格')
        .fontColor(Color.Orange)
    } else {
   
   
      Text('不及格')
        .fontColor(Color.Red)
    }
  }

■ 4. @Builder包含循环的

  // 包含循环的Builder
  @Builder
  listBuilder(items: string[]) {
   
   
    Column() {
   
   
      ForEach(items, (item: string) => {
   
   
        Text(item)
          .fontSize(16)
          .margin(5)
      })
    }
  }

■ 5. @Builder使用列表

@Entry
@Component
struct BuilderExample {
   
   
  // 简单的无参数Builder
  @Builder
  simpleTextBuilder() {
   
   
    Text('Hello World')
      .fontSize(30)
      .fontWeight(FontWeight.Bold)
      .fontColor(Color.Blue)
  }

  // 带参数的Builder
  @Builder
  parameterizedBuilder(text: string, size: number, color: Color) {
   
   
    Text(text)
      .fontSize(size)
      .fontColor(color)
      .fontWeight(FontWeight.Medium)
  }

  // 包含逻辑的Builder
  @Builder
  conditionalBuilder(score: number) {
   
   
    if (score >= 90) {
   
   
      Text('优秀')
        .fontColor(Color.Green)
    } else if (score >= 60) {
   
   
      Text('及格')
        .fontColor(Color.Orange)
    } else {
   
   
      Text('不及格')
        .fontColor(Color.Red)
    }
  }

  // 包含循环的Builder
  @Builder
  listBuilder(items: string[]) {
   
   
    Column() {
   
   
      ForEach(items, (item: string) => {
   
   
        Text(item)
          .fontSize(16)
          .margin(5)
      })
    }
  }

  build() {
   
   
    Column({
   
    space: 20 }) {
   
   
      // 使用无参数Builder
      this.simpleTextBuilder()
      
      // 使用带参数Builder
      this.parameterizedBuilder('自定义文本', 24, Color.Red)
      
      Divider()
      
      // 使用条件Builder
      this.conditionalBuilder(85)
      this.conditionalBuilder(55)
      
      Divider()
      
      // 使用列表Builder
      this.listBuilder(['项目1', '项目2', '项目3', '项目4'])
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

■ 6. @Builder全局定义

// 全局Builder定义
@Builder
function GlobalCard(title: string, content: string) {
   
   
  Column() {
   
   
    Text(title)
      .fontSize(20)
      .fontWeight(FontWeight.Bold)
      .margin({
   
    bottom: 10 })

    Text(content)
      .fontSize(16)
      .fontColor(Color.Gray)
  }
  .padding(15)
  .backgroundColor(Color.White)
  .border({
   
    width: 1, color: Color.Gray })
  .borderRadius(8)
  .width('90%')
  .margin({
   
    bottom: 10 })
}

@Entry
@Component
struct GlobalBuilderExample {
   
   
  build() {
   
   
    Column() {
   
   
      Text('全局Builder示例')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({
   
    bottom: 20 })

      // 使用全局Builder
      GlobalCard('标题1', '这是第一个卡片的内容')
      GlobalCard('标题2', '这是第二个卡片的内容,内容可以更长一些')
      GlobalCard('标题3', '第三个卡片的内容')
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .backgroundColor('#F5F5F5')
    .justifyContent(FlexAlign.Start)
  }
}

■ 7. @Builder 与组件交互

@Entry
@Component
struct InteractiveBuilderExample {
   
   
  @State count: number = 0
  @State text: string = '初始文本'

  // Builder访问组件状态
  @Builder
  counterBuilder() {
   
   
    Row() {
   
   
      Button('减少')
        .onClick(() => {
   
   
          this.count--
        })

      Text(`计数: ${
   
   this.count}`)
        .fontSize(18)
        .margin(10)

      Button('增加')
        .onClick(() => {
   
   
          this.count++
        })
    }
  }

  // Builder访问组件方法
  @Builder
  textInputBuilder() {
   
   
    Column() {
   
   
      TextInput({
   
    text: this.text })
        .onChange((value: string) => {
   
   
          this.text = value
        })
        .width(200)

      Text(`当前文本: ${
   
   this.text}`)
        .fontSize(16)
        .margin({
   
    top: 10 })
    }
  }

  build() {
   
   
    Column({
   
    space: 20 }) {
   
   
      Text('Builder与组件交互示例')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)

      this.counterBuilder()
      this.textInputBuilder()
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

在这里插入图片描述

■ 8. @BuilderParam:使用@Builder 作为参数

  • @BuilderParam 允许将接收@Builder作为参数传递给组件,实现高度可定制的 UI:
@Component
struct CustomCard {
   
   
  // 使用@BuilderParam接收Builder作为参数
  @BuilderParam headerBuilder: () => void
  @BuilderParam contentBuilder: () => void

  build() {
   
   
    Column() {
   
   
      // 使用传入的headerBuilder
      this.headerBuilder()

      Divider()
        .margin(10)

      // 使用传入的contentBuilder
      this.contentBuilder()
    }
    .padding(15)
    .border({
   
    width: 1, color: Color.Gray })
    .borderRadius(8)
    .width('90%')
    .margin(10)
  }
}

@Entry
@Component
struct BuilderParamExample {
   
   
  @Builder
  customHeader() {
   
   
    Row() {
   
   
      Image($r('app.media.icon'))
        .width(30)
        .height(30)
        .margin({
   
    right: 10 })

      Text('自定义标题')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
    }
  }

  @Builder
  customContent() {
   
   
    Text('这是自定义的内容区域,可以包含任何UI组件和布局')
      .fontSize(14)
      .fontColor(Color.Gray)
  }

  @Builder
  anotherHeader() {
   
   
    Text('另一个标题样式'<
方法“/** * 性能测量装饰器工厂函数 * @param moduleName - 模块名 * @param methodName - 方法名(可选,默认为被装饰方法名) * @returns 方法装饰器 * * @remarks * 支持同步和异步方法的性能测量 * 自动处理异常情况,确保测量不会影响正常业务逻辑 * 集成采样率检查,在测量开始前即决定是否进行性能测量 */ export function measurePerformance(moduleName: string, methodName?: string): MethodDecorator { return (target: unknown, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor => { const originalMethod: unknown = descriptor.value; const profiler: PerformanceProfiler = PerformanceProfiler.getInstance(); const config: ProfilerConfig = profiler.getConfig(); // 使用方法名或属性键作为方法名 const actualMethodName: string = methodName || String(propertyKey); // 重新定义方法 descriptor.value = function (...args: unknown[]): unknown { // 在开始时即进行采样判断,避免不必要的性能开销 if (Math.random() >= config.samplingRate) { if (typeof originalMethod === 'function') { return originalMethod.apply(this, args); } return undefined; } const handle: number = profiler.start(moduleName, actualMethodName); try { // 处理原始方法调用 if (typeof originalMethod !== 'function') { profiler.end(handle); return undefined; } const result: unknown = originalMethod.apply(this, args); // 处理异步方法 if (result instanceof Promise) { return result.finally(() => { profiler.end(handle); }); } else { // 同步方法 profiler.end(handle); return result; } } catch (error) { // 确保异常情况下也结束测量 profiler.end(handle); throw error; } }; return descriptor; };” 代码行“ return (target: unknown, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor => {”报错Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck>和"Symbol()" API is not supported (arkts-no-symbol) <ArkTSCheck> 代码行“ const originalMethod: unknown = descriptor.value;”报错Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck> 代码行“ descriptor.value = function (...args: unknown[]): unknown {”报错Use arrow functions instead of function expressions (arkts-no-func-expressions) <ArkTSCheck>和Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck>和Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck> 代码行“ return originalMethod.apply(this, args);”报错"Function.apply", "Function.call" are not supported (arkts-no-func-apply-call) <ArkTSCheck>和Using "this" inside stand-alone functions is not supported (arkts-no-standalone-this) <ArkTSCheck> 代码行“ const result: unknown = originalMethod.apply(this, args);”报错Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck>和"Function.apply", "Function.call" are not supported (arkts-no-func-apply-call) <ArkTSCheck>和Using "this" inside stand-alone functions is not supported (arkts-no-standalone-this) <ArkTSCheck> 代码行“ throw error;”报错"throw" statements cannot accept values of arbitrary types (arkts-limited-throw) <ArkTSCheck>如何修正?
09-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光芒Shine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值