CPU都被干冒烟了,拥抱HarmonyOS第二天,自定义组件(上)

简介: CPU都被干冒烟了,拥抱HarmonyOS第二天,自定义组件

在这两天的学习过程中,我发现了一个巨诡异的事情,那就是明明第一次在文档中找到的内容,结果第二次想要通过搜索找到他,打死都找不到,这种情况出现了三次。arkUI 的文档是真神奇!


那种诡异感甚至差点让我以为自己穿越了...


第二天没有什么实际的产出,但是学习进展非常明显,直接把自定义组件相关的知识 ~


学!完!了!


我把主要学习精力放在了区别 arkUI 和 React/vue 的差异、以及在封装一些比较有难度的基础组件的实现方式上。


比如我想要封装一个体验良好的表单组件,那么我的学习思路是


  • T、学习思路
  • 1、复杂UI布局应该怎么做 ✅
  • 2、基础的动画细节应该如何实现 ✅
  • 3、数据管理应该怎么做 ✅
  • 4、表单验证应该怎么做 ✅
  • 5、数据量复杂的时候有没有可能存在性能问题,还没有验证过,若在实践中遇到问题,针对性的优化即可


如果目的一样,当我攻克了和 React 的差异,在 HarmonyOS 上基于 arkUI 实现一套大厂可商用的基础组件就比较简单了。


这意味着什么呢?


意味着我已经可以开始撸大型实战项目啦!剩下还有很多不熟悉的组件和系统能力,只需要在用到的时候,阅读文档拿来使用,在后续的开发过程中慢慢熟练即可。所以呢,有想要组建 HarmonyOS 开发团队的老板们可以开始联系我了,我给你们当技术指导,哈哈。


我今天学习的主要内容包括:


系统组件生命周期
onAppear:组件挂载到组件树之后调用
onDisAppear:组件卸载时调用
页面组件生命周期
onPageShow:页面每次显示时触发
onPageHide:页面每次隐藏时触发
onBackPress:用户点击返回按钮时触发
自定义组件生命周期
aboutToAppear:组件即将出现时触发,在 build 之前
aboutToDisappear:组件即将销毁时触发
组件级别状态管理
@State
@Prop
@Link
@Provide/@Consume
@Observed
@ObjectLink
应用级别状态管理
@StorageProp
@StorageLink
@LocalStorageProp
@LocalStorageLink
其他状态管理
@Watch
$$ 运算符
T. 状态交互
1. 传参与接受参数
2. 子组件控制父组件
3. 父组件控制子组件

练习了大量的交互 Demo,并成功封装了两个可商用的基础组件

Icon Lottie
字体图标组件 Lottie 动画组件

在 React 里,一个 state 一个 props 就完事了,万万没想到在 arkUI 里知识点这么多。在研究组件交互的过程中,我的 CPU 直接被干冒烟了,根据我的学习感受,这必定会成为一个比较难掌握的点,要吃透他不太容易


01组件分类


在 arkUI 里,组件主要分为三个大类


  • 系统组件 主要是指系统原生提供的一系列组件,例如 Text、Button、CheckBox 等
  • 页面组件 被装饰器 @Entry 装饰的组件为页面组件,他表示一个页面的入口,该组件为页面的根节点
  • 自定义组件 我们可以通过装饰器 @Component 定义新的组件


02组件基础语法


一个页面组件中最基础的写法如下

@Entry
@Component
struct MyComponent {
  build() {
    Text('hello world!')
  }
}

页面组件必须被 @Entry 装饰。build 方法中包含所有的页面元素。在上面这个例子中,Text 组件执行实际上是一个初始化的过程,但是由于关键字 struct 的作用,因此省略了 new.


系统提供的基础组件以 . 链式调用的方式设置当前组件的样式


例如,设置 Text 组件的字体大小

Text('test')
  .fontSize(12)

也可以同时配置多个属性

Image('test.jpg')
  .alt('error.jpg')    
  .width(100)    
  .height(100)

除了直接传递常量参数之外,还可以传递变量和表达式

Text('hello')
  .fontSize(this.size)
Image('test.jpg')
  .width(this.count % 2 === 0 ? 100 : 200)    
  .height(this.offset + 100)

arkUI 系统提供了一些全局的枚举类型,可以作为参数传递

Text('hello')
  .fontSize(20)
  .fontColor(Color.Red)
  .fontWeight(FontWeight.Bold)

如果某个元素想要设置事件监听,同样以 . 链式调用的方式使用

Button('Click me')
  .onClick(() => {
    this.myText = 'ArkUI';
  })


this


习惯了箭头函数和函数式组件的 React 开发者就要注意了,在面向对象的语境下,需要随时确保 this 的引用发生变化,因此如下两种情况都需要使用 bind 绑定 this

Button('add counter')
  .onClick(function(){
    this.counter += 2;
  }.bind(this))

这是个坑啊,折磨了多少开发者,他又来了!

myClickHandler(): void {
  this.counter += 2;
}
...
Button('add counter')
  .onClick(this.myClickHandler.bind(this))


组件嵌套


组件嵌套的方式,就是在父组件后面添加 {},所有的容器组件都支持嵌套子组件

Column() {
  Text('Hello')
    .fontSize(100)
  Divider()
  Text(this.myText)
    .fontSize(100)
    .fontColor(Color.Red)
}


@Builder


有的时候我们希望把一段组件的逻辑单独抽离出来,可以使用 @Builder 装饰器来声明一个自定义构建函数

@Entry
@Component
struct MyComponent {
  @Builder helloHarmonyOS() {
    Text('Hello HarmonyOS')
  }
  build() {
    Row() {
      Text('hello world!')
      this.helloHarmonyOS()
    }
  }
}

但是这个 @Builder 装饰器在传参数的时候,有特别的规则,我们后面在学习状态管理的时候一起分享

我们可以在一个组件里定义多个 @Builder 声明的函数,也可以在全局定义

@Builder 
function MyGlobalBuilderFunction() {
}


@Styles


我们可以使用 @Styles 装饰器来解决样式复用的问题。

@Entry
@Component
struct MyComponent {
  @Builder helloHarmonyOS() {
    Text('Hello HarmonyOS')
      .fancy()
  }
  @Styles fancy() {
    .width('100%')
    .height(40)
    .backgroundColor(Color.Pink)
  }
  build() {
    Row() {
      Text('hello world!')
        .fancy()
      this.helloHarmonyOS()
    }
  }
}

需要注意的是,@Styles 目前仅支持通用属性和通用事件。


具体属性有哪些可以去官方文档查看,或者根据 DevEco 的代码提示来编写


@Styles 也不支持传入参数

// bad
@Styles 
- function globalFancy (value: number) {
-  .width(value)
}

@Styles 可以定义在组件内,也可以定义在全局,在全局定义时需要在方法名之前添加 function 关键字

// 全局
@Styles function functionName() { ... }
// 在组件内
@Component
struct FancyUse {
  @Styles fancy() {
    .height(100)
  }
}

组件内 @Styles 的优先级高于全局 @Styles。 框架优先找当前组件内的 @Styles,如果找不到,则会全局查找。

// 定义在全局的@Styles封装的样式
@Styles function globalFancy  () {
  .width(150)
  .height(100)
  .backgroundColor(Color.Pink)
}
@Entry
@Component
struct FancyUse {
  @State heightValue: number = 100
  // 定义在组件内的@Styles封装的样式
  @Styles fancy() {
    .width(200)
    .height(this.heightValue)
    .backgroundColor(Color.Yellow)
    .onClick(() => {
      this.heightValue = 200
    })
  }
  build() {
    Column({ space: 10 }) {
      // 使用全局的@Styles封装的样式
      Text('FancyA')
        .globalFancy ()
        .fontSize(30)
      // 使用组件内的@Styles封装的样式
      Text('FancyB')
        .fancy()
        .fontSize(30)
    }
  }
}

很坑爹的是,目前 @Styles 还不支持跨文件引入,这里的全局只能是同一个文件的全局 ~


@Extend


我们可以使用 @Extend 扩展原生组件样式

@Extend(UIComponentName) 
function functionName {
  ...
}
  • @Extend 仅支持全局定义
  • @Extend 支持封装指定原生组件的私有属性和方法,以及相同指定组件的 @Extend 方法
// 支持Text的私有属性fontColor
@Extend(Text) function fancy () {
  .fontColor(Color.Red)
}
// superFancyText可以调用预定义的fancy
@Extend(Text) 
function superFancyText(size:number) {
  .fontSize(size)
  .fancy()
}
  • @Extend 支持参数传入
// xxx.ets
@Extend(Text) 
function fancy (fontSize: number) {
  .fontColor(Color.Red)
  .fontSize(fontSize)
}
@Entry
@Component
struct FancyUse {
  build() {
    Row({ space: 10 }) {
      Text('Fancy')
        .fancy(16)
      Text('Fancy')
        .fancy(24)
    }
  }
}

传入的参数可以是 function

@Extend(Text) 
function makeMeClick(onClick: () => void) {
  .backgroundColor(Color.Blue)
  .onClick(onClick)
}
@Entry
@Component
struct FancyUse {
  @State label: string = 'Hello World';
  onClickHandler() {
    this.label = 'Hello ArkUI';
  }
  build() {
    Row({ space: 10 }) {
      Text(`${this.label}`)
        .makeMeClick(this.onClickHandler.bind(this))
    }
  }
}
相关文章
|
6天前
|
Android开发
鸿蒙开发:自定义一个简单的标题栏
本身就是一个很简单的标题栏组件,没有什么过多的技术含量,有一点需要注意,当使用沉浸式的时候,注意标题栏的位置,需要避让状态栏。
鸿蒙开发:自定义一个简单的标题栏
|
12天前
|
安全 API 数据处理
鸿蒙next版开发:ArkTS组件通用属性(隐私遮罩)
在HarmonyOS 5.0中,ArkTS引入了隐私遮罩功能,用于保护用户隐私和数据安全。本文详细介绍了隐私遮罩的通用属性和使用方法,并提供了示例代码。隐私遮罩支持Image和Text组件,在数据加载或处理过程中防止敏感信息泄露,提升用户体验和数据安全性。
37 11
|
12天前
|
开发者 UED 容器
鸿蒙next版开发:ArkTS组件通用属性(Flex布局)
在HarmonyOS next中,ArkTS的Flex布局是一种强大且灵活的布局方式,支持水平或垂直方向排列元素,并能动态调整大小和位置以适应不同屏幕。主要属性包括justifyContent、alignItems、direction和wrap,适用于导航栏、侧边栏和表单等多种场景。示例代码展示了如何使用这些属性创建美观的布局。
45 10
|
12天前
|
开发者 容器
鸿蒙next版开发:ArkTS组件通用属性(文本通用)
在HarmonyOS 5.0中,ArkTS提供了丰富的文本通用属性,如textAlign、maxLines、textOverflow、fontSize、fontColor、fontStyle、fontWeight、fontFamily、lineHeight、letterSpacing和decoration等,用于实现多样的文本显示和样式效果。本文详细解读了这些属性,并提供了示例代码,帮助开发者更好地利用这些工具,提升应用界面的美观和实用性。
46 8
|
12天前
|
开发框架 UED 开发者
鸿蒙next版开发:ArkTS组件通用属性(显隐控制)
在HarmonyOS 5.0中,ArkTS引入了显隐控制属性,允许开发者通过`visibility`属性控制组件的显示与隐藏,优化用户体验和应用性能。本文详细解析了`visibility`属性的三种状态(Visible、Hidden、None)及其应用场景,并通过示例代码展示了如何使用显隐控制属性,避免组件频繁创建和销毁,提升性能。
39 8
|
12天前
|
API UED 开发者
鸿蒙next版开发:ArkTS组件通用属性(透明度设置)
在HarmonyOS 5.0中,ArkTS引入了透明度设置属性`opacity`,允许开发者自定义组件的透明度,从而创建复杂的视觉效果和提升用户体验。本文详细解读了`opacity`属性的用法,并提供了示例代码,展示了如何在不同透明度下展示组件。透明度设置在UI开发中具有多种用途,如创建重叠效果、增强美观性和实现动画效果。
32 7
|
12天前
|
UED 开发者 容器
鸿蒙next版开发:ArkTS组件通用属性(位置设置)
在HarmonyOS next中,ArkTS提供了align、direction、position、markAnchor、offset和alignRules等通用属性,用于精确控制组件在用户界面中的位置和布局。本文详细解读了这些属性,并提供了示例代码进行说明。通过这些属性,开发者可以实现精确布局、动态界面调整和提升用户体验。
49 6
|
12天前
|
UED 开发者
鸿蒙next版开发:ArkTS组件通用属性(边框设置)
在HarmonyOS 5.0中,ArkTS提供了丰富的边框设置属性,允许开发者自定义组件的边框样式,提升应用的视觉效果和用户体验。本文详细解读了border属性的使用方法,并提供了示例代码,展示了如何设置不同边的边框宽度、颜色、圆角和样式。边框设置在UI开发中具有重要作用,如区分组件、强调重要元素和美化界面。
45 6
|
13天前
|
API 开发者
鸿蒙next版开发:ArkTS组件通用属性(浮层)
在HarmonyOS 5.0中,ArkTS的浮层属性(overlay)允许开发者在组件上增加遮罩文本或叠加自定义组件,实现丰富的界面效果。本文详细解读了overlay属性的用法,并提供了示例代码,包括静态和动态浮层的应用。通过本文,读者可以掌握如何在UI开发中有效利用这一功能。
36 6
|
13天前
|
开发者 UED 容器
鸿蒙next版开发:ArkTS组件通用属性(Z序控制)
在HarmonyOS 5.0中,ArkTS引入了Z序控制属性,使开发者能够设置组件的堆叠顺序。本文详细解读了Z序控制的基础知识、zIndex属性及其用途,并提供了示例代码,帮助开发者实现复杂的用户界面和动态交互效果。
41 6