HarmonyOS 之 @Require 装饰器自学指南

简介: 在 HarmonyOS 应用开发中,组件初始化传参校验是常见难题。本文深入探讨了 `@Require` 装饰器的使用方法,它能在编译阶段严格校验组件构造传参,提升代码健壮性与开发效率。文章涵盖装饰器定义、版本支持、限制条件及典型使用场景(如父子组件传参校验和 `@ComponentV2` 初始化),并通过错误示例分析常见问题。总结中强调了 `@Require` 的重要性,助力开发者编写更稳定高效的代码。适合鸿蒙开发者学习参考!

在 HarmonyOS 应用开发工作中,我频繁碰到组件初始化传参校验的难题。在复杂的组件嵌套里,要是无法确保必要参数在构造时准确传入,就极易引发运行时错误,而且排查起来费时费力。一次偶然的机会,我接触到了 ​​@Require​​​ 装饰器,它能在编译阶段就对组件构造传参进行严格校验,大大提升了代码的健壮性和开发效率。然而在学习过程中,我发现相关资料零散且缺乏系统性。因此,我决定撰写这篇博客,把自己的学习经验和实践成果分享出来,助力更多开发者快速掌握 ​​@Require​​ 装饰器的使用方法。

1. HarmonyOS 开发文档概述

HarmonyOS 开发文档为开发者提供了全面且细致的指导,涵盖了从基础入门到高级 API 应用的各个方面。当前使用的是 HarmonyOS 5.0.3 (15) 版本,其 API 能力级别为 API 15 Release。详细的版本配套关系可参考版本说明文档,这有助于我们精准地使用适合当前版本的 API 功能。

2. @Require 装饰器概述

2.1 定义与作用

​@Require​​​ 是一个用于校验 ​​@Prop​​​、​​@State​​​、​​@Provide​​​、​​@BuilderParam​​ 和普通变量(无状态装饰器修饰的变量)是否需要构造传参的装饰器。当它与这些变量结合使用时,在构造自定义组件时,这些变量必须在构造时传参,否则编译将无法通过。

2.2 版本支持情况

  • 从 API version 11 开始,​​@Require​​​ 对 ​​@Prop​​​ 和 ​​@BuilderParam​​ 进行校验,并且支持在元服务中使用。
  • 从 API version 12 开始,它对 ​​@State​​​、​​@Provide​​ 和普通变量(无状态装饰器修饰的变量)进行校验。

3. @Require 装饰器的限制条件

3.1 修饰范围限制

​@Require​​​ 装饰器仅能用于装饰 ​​struct​​​ 内的 ​​@Prop​​​、​​@State​​​、​​@Provide​​​、​​@BuilderParam​​ 和普通变量(无状态装饰器修饰的变量)。如果在其他地方使用,会导致代码不符合规范。

3.2 预览器限制

预览器限制场景需要参考 ​​PreviewChecker​​ 检测规则。这意味着在使用预览器查看组件效果时,需要确保代码符合相关规则,否则可能无法正常预览。

4. @Require 装饰器的使用场景

4.1 父子组件传参校验

当 ​​Child​​​ 组件内使用 ​​@Require​​​ 装饰器和 ​​@Prop​​​、​​@State​​​、​​@Provide​​​、​​@BuilderParam​​​ 和普通变量(无状态装饰器修饰的变量)结合使用时,父组件 ​​Index​​​ 在构造 ​​Child​​ 时必须传参,否则编译不通过。以下是一个示例代码:

@Entry
@Component
struct Index {
  @State message: string = 'Hi, HarmonyOS';

  @Builder buildTest() {
    Row() {
      Text('Hi, Harmony World')
        .fontSize(40)
    }
  }

  build() {
    Row() {
      Child({ 
        regular_value: this.message, 
        state_value: this.message, 
        provide_value: this.message, 
        initMessage: this.message, 
        message: this.message,
        buildTest: this.buildTest, 
        initBuildTest: this.buildTest 
      })
    }
  }
}

@Component
struct Child {
  @Builder buildFunction() {
    Column() {
      Text('initBuilderParam - Custom')
        .fontSize(40)
        .fontColor('#FF8C00')
    }
  }
  @Require regular_value: string = 'Hi';
  @Require @State state_value: string = "Hi";
  @Require @Provide provide_value: string = "Hi";
  @Require @BuilderParam buildTest: () => void;
  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
  @Require @Prop initMessage: string = 'Hi';
  @Require @Prop message: string;

  build() {
    Column() {
      Text(this.initMessage)
        .fontSize(40)
        .fontColor('#008080')
      Text(this.message)
        .fontSize(40)
        .fontColor('#008080')
      this.initBuildTest();
      this.buildTest();
    }
    .width('100%')
    .height('100%')
  }
}

1742871746676.jpg

在这个示例中,父组件 ​​Index​​​ 在构造 ​​Child​​​ 组件时,为 ​​Child​​​ 组件的所有使用 ​​@Require​​ 装饰的变量都传递了参数,确保了编译的顺利通过。同时,对文本的字体大小和颜色进行了修改,增强了视觉效果。

4.2 使用 @ComponentV2 修饰的组件初始化

使用 ​​@ComponentV2​​​ 修饰的自定义组件 ​​ChildPage​​​ 通过父组件 ​​ParentPage​​​ 进行初始化,因为有 ​​@Require​​ 装饰,所以父组件必须进行构造赋值。以下是示例代码:

@ObservedV2
class Info {
  @Trace name: string = '';
  @Trace age: number = 0;
}

@ComponentV2
struct ChildPage {
  @Require @Param childInfo: Info = new Info();
  @Require @Param state_value: string = "Hi";
  build() {
    Column() {
      Text(`ChildPage childInfo name :${this.childInfo.name}`)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FF69B4')
      Text(`ChildPage childInfo age :${this.childInfo.age}`)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FF69B4')
      Text(`ChildPage state_value :${this.state_value}`)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FF69B4')
    }
  }
}

@Entry
@ComponentV2
struct ParentPage {
  info1: Info = { name: "Charlie", age: 35 };
  label1: string = "HarmonyOS Is Great";
  @Local info2: Info = { name: "Charlie", age: 35 };
  @Local label2: string = "HarmonyOS Is Great";

  build() {
    Column() {
      Text(`info1: ${this.info1.name}  ${this.info1.age}`) 
        .fontSize(40)
        .fontWeight(FontWeight.Bold)
        .fontColor('#8A2BE2')
      ChildPage({ childInfo: this.info1, state_value: this.label1}) 
      Line()
        .width('100%')
        .height(8)
        .backgroundColor('#FF0000').margin(15)
      Text(`info2: ${this.info2.name}  ${this.info2.age}`) 
        .fontSize(40)
        .fontWeight(FontWeight.Bold)
        .fontColor('#8A2BE2')
      ChildPage({ childInfo: this.info2, state_value: this.label2}) 
      Line()
        .width('100%')
        .height(8)
        .backgroundColor('#FF0000').margin(15)
      Button("Update info1&info2")
        .onClick(() => {
          this.info1 = { name: "David", age: 28} 
          this.info2 = { name: "David", age: 28} 
          this.label1 = "New Fantastic Message"; 
          this.label2 = "New Fantastic Message"; 
        })
    }
  }
}

在这个示例中,父组件 ​​ParentPage​​​ 在初始化 ​​ChildPage​​​ 组件时,为 ​​ChildPage​​​ 组件的 ​​childInfo​​​ 和 ​​state_value​​ 传递了参数,保证了组件的正常初始化。同时,对文本的字体大小、颜色以及线条的高度、颜色和边距进行了修改,使界面更加美观。

5. 错误场景分析

如果在使用 ​​@Require​​ 装饰器时没有在构造时传参,会导致编译错误。以下是一个错误示例:

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  @Builder buildTest() {
    Row() {
      Text('Hello, world')
        .fontSize(32)
    }
  }

  build() {
    Row() {
      Child()
    }
  }
}

@Component
struct Child {
  @Builder buildFunction() {
    Column() {
      Text('initBuilderParam - Error Case')
        .fontSize(32)
        .fontColor('#FF00FF')
    }
  }
  // 使用@Require必须构造时传参。
  @Require regular_value: string = 'Hello';
  @Require @State state_value: string = "Hello";
  @Require @Provide provide_value: string = "Hello";
  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
  @Require @Prop initMessage: string = 'Hello';

  build() {
    Column() {
      Text(this.initMessage)
        .fontSize(32)
        .fontColor('#FF00FF')
      this.initBuildTest();
    }
  }
}

1742913471280.jpg

在这个示例中,父组件 ​​Index​​​ 在构造 ​​Child​​​ 组件时没有传递任何参数,由于 ​​Child​​​ 组件中的变量使用了 ​​@Require​​ 装饰器,所以这段代码在编译时会报错。同时,对文本的字体大小和颜色进行了修改,方便区分不同的代码部分。

6. 总结

​@Require​​​ 装饰器在 HarmonyOS 开发中是一个非常实用的工具,它可以帮助我们在编译阶段就发现组件构造传参的问题,避免运行时错误,提高代码的稳定性和可维护性。通过本文的介绍,你应该对 ​​@Require​​​ 装饰器的使用有了更深入的理解。在实际开发中,合理运用 ​​@Require​​ 装饰器,能够让你的代码更加健壮,开发过程更加顺畅。

最后希望这篇自学指南能对你有所帮助,让你在 HarmonyOS 开发的道路上更进一步,当然对鸿蒙有兴趣的同学也欢迎点赞、收藏~!

目录
相关文章
|
21天前
|
开发者
HarmonyOS NEXT - 样式装饰器:@Styles和@Extend
简介:本文介绍了用于提升代码简洁性和样式复用性的装饰器@Styles和@Extend。@Styles可将多条样式提取为方法,在组件声明处调用,支持静态样式复用;其缺点是仅支持通用属性与事件,且不支持参数。@Extend用于扩展原生组件样式,支持封装私有属性、事件及全局方法,允许传参(包括状态变量和函数)。此外,stateStyles结合@Styles可根据组件状态动态设置样式,增强灵活性。通过实例演示了这些工具在实际开发中的应用,帮助开发者优化样式管理与维护效率。
88 9
|
22天前
|
API 开发者 UED
HarmonyOS:ComposeTitleBar 组件自学指南
本文详解了鸿蒙开发中 ComposeTitleBar 组件的使用方法与技巧,从基础导入到属性配置,再到实际代码示例,帮助开发者构建美观实用的标题栏。组件自 API Version 10 起支持,具备独立功能结构,核心属性包括 `title`(必填)、`subtitle`(可选)和 `menuItems`(右侧菜单列表)。文章通过具体示例展示了如何配置标题、副标题及菜单项,并提供了交互优化、样式定制与多设备适配的建议。掌握这些内容,可显著提升应用界面体验。如果你有所收获,别忘了点赞收藏!
39 8
|
22天前
|
数据管理 API 开发者
HarmonyOS:ArkTS RowSplit 组件自学指南
在 ArkTS 开发中,复杂界面布局需求常见,尤其需要灵活调整子组件宽度时,传统方式难以满足动态交互需求。`RowSplit` 组件解决了这一问题,支持横向布局并插入可拖动的分割线,让用户轻松调整子组件宽度,提升体验。本文详细介绍了 `RowSplit` 的功能、接口、属性及使用示例,帮助开发者掌握其用法,并总结了注意事项。通过合理配置,可实现灵活美观的布局效果。希望对您有帮助,欢迎关注、点赞和收藏!
68 31
|
22天前
|
API 开发者 UED
HarmonyOS:ArkTS 多态样式自学指南
本文介绍了 ArkTS 多态样式功能,帮助开发者为组件设置不同状态(如点击、按下、禁用等)下的样式。从 API Version 8 开始支持,API Version 11 引入 `attributeModifier` 动态设置属性。核心接口 `stateStyles` 支持多种状态,如 `normal`、`pressed`、`disabled` 等。文章通过示例代码展示了如何为 `Text` 和 `Radio` 组件设置多态样式,结合状态控制实现动态视觉反馈。掌握此功能可提升用户体验,推荐开发者根据需求灵活运用。
65 27
|
22天前
|
API 开发者
HarmonyOS:ArkTS Path 组件自学指南
在鸿蒙应用开发中,绘制复杂图形常面临传统布局方式难以满足需求的问题。ArkTS 的 Path 组件提供了解决方案,如同一把“神奇画笔”,支持通过灵活的命令和属性绘制直线、曲线、椭圆弧等多样图形。本文详细介绍了 Path 组件从 API Version 7 起的功能特性,包括 `commands`、`fill`、`stroke` 等核心属性,以及各类绘图命令如 `M`(移动)、`L`(直线)、`C`(贝塞尔曲线)等。结合示例代码,展示了如何绘制简单直线到复杂曲线图形,并拓展了颜色、透明度和线条样式的自定义方法。掌握 Path 组件,可为应用带来更丰富生动的视觉体验,助力开发者实现创意绘图需求。
63 21
|
25天前
|
编解码 搜索推荐 API
鸿蒙栅格布局组件 GridRow 自学指南
在鸿蒙应用开发中,布局设计常因设备分辨率差异而面临挑战。传统固定布局可能导致组件挤压或显示错乱,而 GridRow 组件提供了灵活解决方案。它从 API Version 9 起支持栅格布局,搭配 GridCol 子组件实现强大适配能力。本文详解 GridRow 的参数、属性与事件,如 `columns`、`gutter`、`breakpoints` 等,并通过实战示例展示其应用。掌握 GridRow,助你轻松应对多尺寸设备布局需求,打造精美界面。
45 7
|
25天前
|
API UED 开发者
HarmonyOS:动画 motionPath 、 animateToImmediately API自学指南
在鸿蒙应用开发中,动画是提升用户体验的关键。本文针对初学者面对众多动画API时的困惑,重点解析两个实用API:`motionPath`和`animateToImmediately`。前者通过精细控制组件运动路径(如SVG字符串定义轨迹),实现灵动位移动画;后者从API Version 12起支持显式动画立即下发,结合状态变化打造流畅动画序列。文中提供详细参数说明与示例代码,帮助开发者快速掌握技巧,让应用更生动。
52 8
|
25天前
|
前端开发 JavaScript API
HarmonyOS:ArkTS 显式动画 animateTo 自学指南
本文深入解析了 ArkTS 中的 `animateTo` 全局显式动画接口,帮助开发者掌握其使用方法。文章从接口概述、参数详解到使用注意事项,结合实际示例代码,全面展示了如何通过配置 `AnimateParam` 对象实现流畅的动画效果。内容涵盖属性动画、布局变化及组件转场等场景,并强调不同版本的支持特性。适合初学者系统学习,也供进阶开发者参考优化动画体验。希望本文能助你快速上手 `animateTo`!
81 7
|
26天前
|
缓存 监控 开发者
HarmonyOS @Reusable 装饰器自学指南:高性能组件复用实战指南
在 HarmonyOS 开发中,组件性能优化至关重要。本文聚焦 @Reusable 装饰器的组件复用机制,从核心原理到实战场景深入解析。通过列表性能优化、复杂布局动态更新等案例,结合生命周期管理与状态策略,提供系统化学习路径。同时,针对常见问题提出解决方案,并给出架构设计建议。掌握 @Reusable 不仅能提升性能(实测 30%-50%),还能优化开发流程。适合开发者进阶参考!
55 0
|
26天前
|
缓存 算法 数据可视化
HarmonyOS人脸比对技术自学指南与实战分享
本文详解了如何基于HarmonyOS Core Vision Kit实现人脸相似度比对功能,适用于娱乐类APP开发。通过`faceComparator`模块,简化了检测、特征提取与比对流程,支持端侧离线处理。文章涵盖技术架构解析、开发准备、UI设计及核心逻辑实现,并提供性能优化、异常处理及多人比对扩展方案。重点包括置信度分级、LRU缓存、隐私合规设计,助力开发者快速构建高效稳定的功能。
52 0