写点什么

HarmonyOS 之 @Require 装饰器自学指南

作者:李游Leo
  • 2025-03-26
    北京
  • 本文字数:3814 字

    阅读完需:约 13 分钟

HarmonyOS 之 @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@Componentstruct 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 }) } }}
@Componentstruct 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%') }}
复制代码



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

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

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

@ObservedV2class Info {  @Trace name: string = '';  @Trace age: number = 0;}
@ComponentV2struct 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@ComponentV2struct 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@Componentstruct Index {  @State message: string = 'Hello World';
@Builder buildTest() { Row() { Text('Hello, world') .fontSize(32) } }
build() { Row() { Child() } }}
@Componentstruct 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(); } }}
复制代码



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

6. 总结

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

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


发布于: 1 小时前阅读数: 7
用户头像

李游Leo

关注

全栈开发工程师、全栈讲师、华为HDE 2022-07-14 加入

原百度、时趣互动、乐视高级前端(软件)开发工程师。后在北京一所当地大学任教,主要职务是教学主任,也为网易云课堂微专业的前端课程负责人。

评论

发布
暂无评论
HarmonyOS 之 @Require 装饰器自学指南_HarmonyOS NEXT_李游Leo_InfoQ写作社区