鸿蒙HarmonyOS自定义组件开发和使用

自定义组件的介绍

在开发和使用自定义组件直接,我们需要了解什么是自定义组件?

ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。

自定义组件具有以下特点:

  • 可组合:允许开发者组合使用系统组件、及其属性和方法。

  • 可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用。

  • 数据驱动UI更新:通过状态变量的改变,来驱动UI的刷新。

我们可以这么理解:自定义组件就是通过各种基础组件的组合,封装为可重用,可组合的UI单元。

自定义组件的基本用法

场景描述:

在日常开发中,我们拿到设计稿后,通过对页面内容进行合理抽象,提取出结构相同以及功能明确的UI单元,组合为自定义组件。

案例:

下面我们以一个实例来说明自定义组件的基本用法:

比如我们需要完成一个待办事项列表的页面开发,除了标题栏,选项卡都是内容重复的,那么我们就可以把这个卡片抽象出一个自定义组件

具体代码如下:

@Preview
@Component
export struct ToDoItem {
  private content?: string;
  //定义状态变量
  @State isComplete: boolean = false

  build() {
    Row() {
      //建立状态与视图间的关系
      if (this.isComplete) {
        Image($r('app.media.check_select')).width(30)
      } else {
        Image($r('app.media.check_normal')).width(30)
      }
      Text(this.content??'自定义组件').fontColor(Color.Black)
        .opacity(this.isComplete ? 0.4 : 1)

    }
    .width('100%')
    .height(40)
    .padding({ left: 16 })
    .margin({ top: 10 })
    .borderRadius(20)
    .backgroundColor(Color.White)
    .onClick(() => {
        //通过点击事件改变状态,达到交互效果
      this.isComplete = !this.isComplete
    })
  }
}

自定义变量isComplete来控制选项卡的状态,在build函数里通过if/else条件渲染语句来描述状态发生后变化的UI,在用户点击onClick后改变状态,ArkUI会自动帮我们渲染出新的UI界面。

具体使用:

import { ToDoItem } from './widget/ToDoItem'

@Preview
@Entry
@Component
struct TodoListPage {
  totalTasks: Array<string> = [];

  aboutToAppear() {
    this.totalTasks = [
      '早起晨读',
      '准备早餐',
      '阅读名著',
      '学习ArkTs',
      '看个电影',
    ]
  }

  build() {
    Column() {
      Text('代办列表')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
      ForEach(this.totalTasks, (task: string) => {
        ToDoItem({ content: task })
      })
    }.backgroundColor(Color.Gray)
    .height('100%')

  }
}

 这样一个有自定义组件的页面就完成了。

注意:我们通过forEach循环把自定义组件添加到页面上,但是forEach必须在容器组件中,不能作为根节点使用。

公共组件的封装

上面的案例是多组件组合为一个自定义组件只针对单个页面,接下来我们进行公共组件的封装

场景描述

我们在应用开发过程中,不同的业务场景,有可能需要使用相同功能和样式的ArkUI组件。例如,登录页面登录按钮, 购物页面结算按钮可能样式相同。该场景常用方法是抽取相同样式的逻辑部分,并将其封装成一个自定义组件到公共组件库中。在业务场景开发时,统一从公共组件库获取封装好的公用组件。

示例

以最常用的BUtton组件为例,当多个业务场景需要使用相同风格样式的Button组件时,我们可以把通用的逻辑封装成一个自定义组件,在通用多级中定制公共的属性,然后将自定义Button以拓展组件的形式集成到公共组件库中,提供给其他team使用,如果要做到尽善尽美,可能需要穷举所有Button的属性。当然可以自行调整。自定义组件的代码如下

@Component
struct CommonButton {
  @Prop text: string = '';
  @Prop stateEffect: boolean = true;
  // ...穷举所有Button独有属性
  
  build() {
    Button(this.text)
      .fontSize(12)
      .fontColor('#FFFFFF')
      .stateEffect(this.stateEffect)// stateEffect属性的作用是控制默认点击动画
      .xxx //穷举Button其他独有属性赋值
  }
}

在使用自定义Button 组件时,若需修改组件显示内容text和点击动画效果stateEffect时(其他Button独有的属性用法相同),需要以参数的形式传入

@Component
struct Index {
  build() {
    MyButton({ text: '点击带有动效', stateEffect: true, ... }) // 入参包含MyButton 组件中定义的全部 Button独有属性
  }
}

但是这样做也有不少缺点,没有使用系统组件那么方便,因为系统的Button组件是链式调用的方法设置,而自定义后只能通过可选参数形式传入,也不利于后期维护,不易拓展,假如升级到新版本,不分组件的属性发生变更(Harmony Next后可能会有重大变化),自定义组件和使用的地方都需要改动,需要慎用。

组件与页面的生命周期:

有过移动开发经验的同学都清楚,自定义组件需要了解组件和页面声明周期的关系,才有助于我们更好的开发自定义组件,我们先看看ArkUI框架下页面的生命周期:

页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。

  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。

  • onBackPress:当用户点击返回按钮时触发。

组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。

  • onDidBuild:组件build()函数执行完成之后回调该接口,不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。

  • aboutToDisappear:aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

总结

目前自定义组件的用法就是以上几种方式,待HarmonyOS Next发布后,如果有更新我会在此基础上进行迭代,如果有兴趣的同学还请持续关注我或者订阅我的专栏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/753837.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

操作系统之《处理器机调度算法》【知识点+详细解题过程】

目录 PS:处理机调度算法相关公式&#xff1a; 1、【FCFS】先来先服务调度算法 2、【SJF&#xff08;SPF&#xff09;】短作业&#xff08;进程&#xff09;优先调度算法 3、【HRRF】最高响应比优先算法 4、【SRTF】最短剩余时间优先调度算法&#xff08;抢占式&am…

图解支付账务系统入门

这篇文章主要从研发的视角讲清楚&#xff1a;账务相关的一些基础概念&#xff0c;账务系统核心的职责&#xff0c;以及一些关键模块的设计要点。 进入正题前&#xff0c;先讲个小故事。 几年前一个狂风暴雨电闪雷鸣的下午&#xff0c;老板把负责账务系统的技术经理炒了鱿鱼&a…

Android 14 独立编译 Setting apk

我们在setting 目录下是用 mm 会报错。 所以应该在 源码主目录 采用 make Settings 进行编译 很多时候如果在apk 目录下 mm 单独编译会出错&#xff0c; 都可以才用这种方式进行编译。

Electron录制应用-打包静态文件问题【命令行ffmpeg导不出视频】

问题描述 在开发环境下,所有功能都运行正常,但一旦进行打包并运行生产环境的版本,导出mp4视频的功能就失效了。没有文件生成,也没有任何错误提示。 排查问题 为了找到问题的根源,我首先决定通过日志来追踪。我使用了winston和winston-daily-rotate-file这两个强大的日志…

招聘,短信与您:招聘人员完整指南

招聘人员面临的最大挑战之一就是沟通和联系候选人。为何?我们可以从以下原因开始&#xff1a;候选人通常被太多的招聘人员包围&#xff0c;试图联系他们&#xff0c;这使得你很难吸引他们的注意。在招聘过程的不同阶段&#xff0c;根据不同的工作量&#xff0c;让申请人保持最…

HBuilder X 小白日记01

1.创建项目 2.右击项目&#xff0c;可创建html文件 3.保存CtrlS&#xff0c;运行一下 我们写的内容&#xff0c;一般是写在body里面 注释的快捷键&#xff1a;Ctrl/ h标签 <h1> 定义重要等级最高的(最大)的标题。<h6> 定义最小的标题。 H标签起侧重、强调的作用…

【R语言】plot输出窗口大小的控制

如果需要输出png格式的图片并设置dpi&#xff0c;可采用以下代码 png("A1.png",width 10.09, height 10.35, units "in",res 300) 为了匹配对应的窗口大小&#xff0c;在输出的时候保持宽度和高度一致即可&#xff0c;步骤如下&#xff1a; 如上的“10…

vue2axios的使用

1.安装axios npm i axios 2.配置代理服务器 1.在config.js中配置单个代理服务器 // 开启代理服务器 需要重新启动项目devServer: {proxy: http://localhost:5000}配置简单&#xff0c;请求资源时直接发给前端&#xff08;8080&#xff09;即可&#xff1b;但不能配置多个代理…

11.常见的Transforms(二)

常见的Transforms&#xff08;二&#xff09; 1.Resize() 的使用 1.1 作用 resize可以把输入的图片按照输入的参数值重新设定大小。 1.2 所需参数 需要输入想要重新设定的图片大小。 输入的参数类型可以为包含长和宽数值的一个序列&#xff08;h,w&#xff09;或者一个整…

css做旋转星球可举一反三

<!DOCTYPE html> <html lang"en"><head> <meta charset"UTF-8" /> <title>旋转的星球</title> <style type"text/css">.box {/*position: relative;*/position: absolute;width: 139px;height: 139p…

ASUS/华硕幻13 2022 GV301R系列 原厂Windows11系统

安装后恢复到您开箱的体验界面&#xff0c;带原机所有驱动和软件&#xff0c;包括myasus mcafee office 奥创等。 最适合您电脑的系统&#xff0c;经厂家手调试最佳状态&#xff0c;性能与功耗直接拉满&#xff0c;体验最原汁原味的系统。 原厂系统下载网址&#xff1a;http:…

pdf合并,这三种方法学会了吗?

在信息爆炸的时代&#xff0c;PDF文档凭借其跨平台、不易修改的特性&#xff0c;成为了我们工作和学习中不可或缺的一部分。然而&#xff0c;当面对多个PDF文件需要合并成一个完整的文档时&#xff0c;许多人可能会感到头疼。今天&#xff0c;就让我们一起来探讨三种高效的PDF合…

【python】socket通信代码解析

目录 一、socket通信原理 1.1 服务器端 1.2 客户端 二、socket通信主要应用场景 2.1 简单的服务器和客户端通信 2.2 并发服务器 2.3 UDP通信 2.4 文件传输 2.5 HTTP服务器 2.6 邮件发送与接收 2.7 FTP客户端 2.8 P2P文件共享 2.9 网络游戏 三、python中Socket编…

戴尔md3400存储控制器脱机故障 电池故障处理

看了一下网上关于DELL MD系列存储故障处理的文档还是比较少的&#xff0c;最近处理了一些关于MD系列存储的问题&#xff0c;稍微整理整理就分享一下&#xff0c;各位喜欢摸索的朋友可以稍稍做些参考&#xff0c;当然如果想寻求外援的也可以快速的找到合适的人。以便安全又快捷的…

SBTI(科学碳目标)认证是什么?

SBTI认证&#xff0c;全称为“科学基础目标设置倡议”&#xff08;Science-Based Targets initiative&#xff09;认证&#xff0c;是一种广泛认可的企业可持续发展标准。以下是关于SBTI认证的详细解释&#xff1a; 一、认证目标 SBTI认证旨在推动企业采取可持续的经营实践&a…

Android进阶之路 - DialogFragment有没有了解的必要?

几个月前写到了弹框业务&#xff0c;以前经常用Dialog、ButtomDialog 、popupWindow 组件&#xff0c;为了契合项目结构参考了原有的 DialogFragment 组件&#xff0c;特此予以记录 我一般在项目中写弹框组件的话&#xff0c;主要用到 alertDialog、popupWindow 组件&#xff0…

S32K3 工具篇2:如何在S32DS中使用Segger JLINK下载

S32K3 工具篇2&#xff1a;如何在S32DS中使用Segger JLINK下载 一&#xff0c; S32DS中JLINK下载1.1 Segger JLINK 驱动1.2 S32DS JLINK驱动路径配置1.3 S32DS JLINK debug configuration1.4 S32DS JLINK debug S32K3板子结果 二&#xff0c; JLINK驱动实现S32K344代码下载2.1 …

【Sublime】Sublime Text 中运行终端

Sublime Text 本身并不是一个终端仿真器&#xff0c;可以使用插件来在 Sublime Text 中集成终端功能。最常用的插件之一是“Terminal”。 使用“Terminal”插件在 Sublime Text 中启动终端 以下是安装和使用该插件的步骤&#xff1a; 安装 Package Control&#xff1a; 如果你…

【IJCAI2024】LeMeViT: Efficient Vision Transformer with Learnable Meta Tokens

【IJCAI2024】LeMeViT: Efficient Vision Transformer with Learnable Meta Tokens for Remote Sensing Image Interpretation 论文&#xff1a;https://arxiv.org/abs/2405.09789 代码&#xff1a;https://github.com/ViTAE-Transformer/LeMeViT 由于相邻像素和图像块之间的高…

Thermo Fisher Scientific赛默飞检测扫描架IPC电路板维修WAH402290

美国Thermo Fisher赛默飞世尔光谱仪IS10 IS5光谱仪主板维修iCAP6000/iCAP7000/iCAP7400&#xff1b;热电质朴分析仪电路板维修 公司仪器维修设备备有三相交流电源,变频电源&#xff0c;无油空压气源&#xff0c;标准化的维修平台、电子负载&#xff0c;耐压测试仪、老化台车和各…