HarmonyOS 之 @Require 装饰器自学指南

ops/2025/4/1 7:30:29/

在 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%')}
}

在这个示例中,父组件 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();}}
}

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

6. 总结

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

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


http://www.ppmy.cn/ops/170018.html

相关文章

Qwen-VL系列多模态大模型技术演进-模型架构、训练方法、数据细节

记录一下Qwen-VL系列多模态大模型技术演进-模型架构、训练方法、数据细节,仅供参考。 系列模型的应用场景: Qwen-VL:基础图像理解和对话。Qwen2-VL:图像短视频理解,代理任务。Qwen2.5-VL:长视频、复杂文档…

Excel(函数进阶篇):FILTER函数全解读、XLOOKUP函数全解读、UNIQUE函数、数组与数组公式

目录 数组与数组函数office365中VLOOKUP函数的加强数组中的多条件判断FILTER函数详解用法概述函数语法 基础筛选多条件筛选进阶技巧结合动态数组 高级函数整合错误处理注意事项FILTER经典问题:一对多查询 XLOOKUP函数XLOOKUP基础用法XLOOKUP函数多条件匹配和双向查询…

STM32八股【2】-----ARM架构

1、架构包含哪几部分内容 寄存器处理模式流水线MMU指令集中断FPU总线架构 2、以STM32为例进行介绍 2.1 寄存器 寄存器名称作用R0-R3通用寄存器用于数据传递、计算及函数参数传递;R0 也用于存储函数返回值。R4-R12通用寄存器用于存储局部变量,减少频繁…

solana增加流动性和删除流动性

在 Solana 区块链上增加和删除流动性通常通过去中心化交易所(DEX)实现,例如 Raydium 或 Orca。以下是详细的操作流程和注意事项: 一、增加流动性 步骤: 1. 连接钱包 使用支持 Solana 的钱包(如 Phantom、…

电机控制常见面试问题(十八)

文章目录 一.电机控制高级拓扑结构1.LLC 二.谈谈电压器饱和后果三.电压器绕组连接方式的影响四.有源逆变的条件 一.电机控制高级拓扑结构 1.LLC LLC是什么?—— 一个会"变魔术"的电源盒子 想象你有一个魔法盒子,能把电池的电压变大或变小&…

流式ETL配置指南:从MySQL到Elasticsearch的实时数据同步

流式ETL配置指南:从MySQL到Elasticsearch的实时数据同步 场景介绍 假设您运营一个电商平台,需要将MySQL数据库中的订单、用户和产品信息实时同步到Elasticsearch,以支持实时搜索、分析和仪表盘展示。传统的批处理ETL无法满足实时性要求&…

华为OD机试2025A卷 - 游戏分组/王者荣耀(Java Python JS C++ C )

最新华为OD机试 真题目录:点击查看目录 华为OD面试真题精选:点击立即查看 题目描述 2020年题: 英雄联盟是一款十分火热的对战类游戏。每一场对战有10位玩家参与,分为两组,每组5人。每位玩家都有一个战斗力,代表着这位玩家的厉害程度。为了对战尽可能精彩,我们需要…

FPGA中串行执行方式之计数器控制

FPGA中串行执行方式之计数器控制 使用计数器控制的方式实现状态机是一种简单且直观的方法。它通过计数器的值来控制状态的变化,从而实现顺序逻辑。计数器的方式特别适合状态较少且状态转移是固定的场景。 基本原理 计数器控制的状态机 ​例程1:简单的顺序状态机 以下是一个…