ArkUI
系统组件
功能组件
信息常用类功能组件
信息展示类
-
Text组件 -
Image组件 -
LoadingProgress加载动效组件 -
QRCode二维码组件
Text('信息类组件')
// 2.图片组件
// 在线图片
Image('https://foruda.gitee.com/avatar/1750745604966482011/9556293_mayuanwei_1750745604.png!avatar200')
.width(100)
// 本地资源图片
Image($r('app.media.notes'))
.width(100)
// 系统图标:部分图片只设置宽度无法加载,需要宽高同时设置才能展示
Image($r('sys.media.ohos_ic_public_add'))
.width(100)
.height(100)
// 3.加载动效组件
LoadingProgress().width(100)
// 4.二维码组件
QRCode('Dxin').width(100)
信息输入类
- 文本输入框
- 搜索框
- 滑动条
- 按钮
TextInput() //单行文本输入框
TextArea() //多行文本输入框
Search() //搜索框
Slider() // 滑动组件
Button('按钮') //按钮组件
信息选择类
需要设置对应组件参数
单选
Row() {
Text('男')
Radio({ value: "男", group: "gender" })
}
Row() {
Text('女')
Radio({ value: "女", group: "gender" })
}
多选
Checkbox()
.shape(CheckBoxShape.CIRCLE)
Checkbox()
.shape(CheckBoxShape.ROUNDED_SQUARE)
下拉框
// 下拉框
Select([{ value: 'dxin' }, { value: '帝心' }])
切换
- 创建包含子组件的Toggle。当
ToggleType为Button时,只能包含一个子组件,如果子组件有文本设置,则相应的文本内容会显示在按钮上。 - 通过
selectedColor属性设置Toggle打开选中后的背景颜色。 - 通过
switchPointColor属性设置Switch类型的圆形滑块颜色,仅对type为ToggleType.Switch生效。
// 当ToggleType为Button时,只能包含一个子组件,如果子组件有文本设置,则相应的文本内容会显示在按钮上。
Toggle({ isOn: true, type: ToggleType.Button }) {
Text('切换')
}
// 通过selectedColor属性设置Toggle打开选中后的背景颜色。
.selectedColor('#ffe59f9f')
Toggle({ type: ToggleType.Checkbox })
.selectedColor('#ffc45151')
Toggle({ isOn: true, type: ToggleType.Switch })
// 通过switchPointColor属性设置Switch类型的圆形滑块颜色,仅对type为ToggleType.Switch生效。
.switchPointColor('#ccc')
Toggle案例

import { promptAction } from '@kit.ArkUI'
@Entry
@ComponentV2
struct ChoseExam {
@Local flag: string = 'Off'
build() {
Column({ space: 30 }) {
Text('Bluetooth Mode:' + this.flag)
Row() {
Text('Bluetooth')
// .layoutWeight(1)
Blank()
Toggle({ type: ToggleType.Switch })
.onChange((isOn: boolean) => {
if (isOn) {
this.flag = 'On'
promptAction.openToast({
message: 'Bluetooth Mode:On',
// duration: 3000
// bottom:400
})
} else {
this.flag = 'Off'
promptAction.openToast({
message: 'Bluetooth Mode:Off'
})
}
})
}
.width('100%')
.height(60)
.backgroundColor('#fff')
.padding({ left: 20, right: 30 })
// .justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.theme_color'))
}
}
常用功能组件
- 日期选择器
DatePicker - 信息标记
Badge - 评分
Rating - 密码锁
PatternLock
// 日期选择器
DatePicker()
.height(150)
// 时间选择器
TimePicker()
.height(150)
// 信息标记
Badge({ count: 3, style: {} }) {
// 要标记的内容
Image($r('sys.media.ohos_ic_public_scan'))
.width(100)
}
// 打分
Rating()
// 密码锁
PatternLock()
.width(200)
-
列表组件
List+ListItem -
轮播Swiper
-
Swiper的尺寸靠内容撑开
-
-
滚动
Scroll- 使用
Scroll时需要注意:- 子组件内容需要超出父组件才会滚动
Scroll只能有一个子组件
- 使用
布局组件
ArkUI常见布局:
-
线性布局:水平或垂直排列的布局
-
Row:水平排列,垂直居中 -
Column:垂直排列,水平居中 -
共同点:
- 不给定大小时,大小由内容决定
- 给定大小时,内容超出不换行
-
-
层叠布局:元素可以重叠的布局
Stack:后一个子组件层叠在上一个子组件之上,默认居中对齐
-
弹性布局:对子元素进行排列、对齐、和分配剩余空间的布局
Flex:- 可以换行,设置元素的间距
- 可以设置子元素主轴交叉轴对其方式
-
栅格布局:规律性划分行列结构,指定子元素占位的布局
GridRow+GridCol:设置容器GridRow的总列数,填充子元素GridColGridRow默认分为四列,通过组件参数columns修改总列数,通过gutter参数设置每一列上下左右的间距。GridCol默认占一列。通过组件参数span修改占了几列。order参数默认为0,可以修改序号来控制摆放的先后顺序。
interface GridColItem {
value: string
order: number
}
@Entry
@Component
struct GridLayout {
arr: GridColItem [] = [
{value:'0',order:13},
{value:'1',order:8},
{value:'2',order:9},
{value:'3',order:10},
{value:'4',order:4},
{value:'5',order:5},
{value:'6',order:6},
{value:'7',order:0},
{value:'8',order:1},
{value:'9',order:2},
{value:'x',order:3},
{value:'-',order:7},
{value:'+',order:11},
{value:'÷',order:12},
{value:'·',order:14},
{value:'=',order:15},
]
build() {
Column({ space: 30 }) {
GridRow({ columns: 4 ,gutter:3}) {
GridCol({ span: 4 }) {
TextInput()
.backgroundColor('#fff')
}
ForEach(this.arr, (item: GridColItem, index) => {
GridCol({order:item.order}) {
Text(item.value)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
.height(50)
.backgroundColor(item.order===15 ? '#ff99e3c5' : '#ffe9b5b5')
})
}
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.theme_color'))
.padding({top:12})
}
} -
相对布局:设置子元素相对位置关系的布局
RelativeContainer
-
选项卡布局:设置页签和内容视图切换的布局
Tabs+TabContent:选项卡组件,通过页签进行内容视图切换的容器组件,每个页签对应一个内容试图。TabContent组件的tabBar属性设置页签。Tabs的组件参数barPosition控制页签的位置。Tabs的属性方法vertical设置页签是否垂直。
常用组件的通用属性
尺寸类属性
| 属性名 | 说明 |
|---|---|
| width | 宽 |
| height | 高 |
| size | 宽和高的综合写法 |
aspectRatio | 设置组件的宽高比 |
layoutWeight: | 设置组件在主轴占比 |
margin: | 设置组件外边距 |
padding: | 设置组件内边距 |
constraintSize | 设置约束尺寸,主要用于尺寸范围的控制 |
位置类属性
| 属性 | 说明 |
|---|---|
position: | 绝对定位,确定子组件相对父组件内容区的位置。自身不占位置。 |
offset: | 相对偏移,组件相对原本的布局位置进行偏移。和position一起使用时,position生效,offset不生效 |
| 背景类属性 | |
|---|---|
backgroundImage: | 设置组件的背景图 |
backgroundImageSize: | 设置组件的背景图尺寸 |
backgroundBlurStyle: | 设置组件背景材质模糊。(可以实现类似渐变色的效果) |
| 边框类属性 | |
|---|---|
border: | 设置组件的边框 |
borderRadius: | 设置组件的边框圆角 |
clip: | 设置是否裁剪子组件超出自身范围的区域 |
| 图形变换类属性 | |
|---|---|
rotate: | 设置组件的旋转 |
translate: | 设置组件的平移 |
scale: | 设置组件的缩放 |
阴影shadow
shadow(options: Optional<ShadowOptions | ShadowStyle>): T
入参类型为ShadowOptions时,可以指定模糊半径、阴影的颜色、X轴和Y轴的偏移量、内外填充模式。
入参类型为ShadowStyle时,可指定不同阴影样式。
Row() {}.width(20).height(150).borderRadius(10)
.backgroundColor('#ffe76666')
//.shadow(ShadowStyle.OUTER_DEFAULT_LG)
.shadow({
radius: 30,
// type: ShadowType.BLUR, // 模糊阴影。模糊方式,那就没有颜色效果了
type: ShadowType.COLOR, // 颜色阴影
color: '#ff0e3991',
offsetX: -30,
offsetY: 20,
fill: false //阴影在外部填充
})
颜色渐变属性
linearGradient线性渐变
linearGradient(options: Optional<LinearGradientOptions>): T
| LinearGradientOptions | 说明 | |
|---|---|---|
| colors | 必选 | 指定渐变色颜色和其对应的百分比位置的数组 |
| angle | 线性渐变的起始角度。角度为0度时渐变方向为从下往上(即0点方向)。0点方向顺时针旋转为正向角度。 | |
| direction | 线性渐变的方向,设置angle为非undefined后不生效。设置为GradientDirection.None时,按默认方向渐变。默认值:GradientDirection.Bottom。 | |
| repeating | 为渐变的颜色重复着色。 |
注意点:
- angle与direction两者选一即可,若同时设置,则只有angle生效
- 若参数repeating为true,则colors数组中任何元素的百分比位置都不应该为1。
- 若colors数组中最后一个元素的百分比位置小于1,且不重复着色,则从该处往后一直都是该纯色。
- 颜色数组中,number表示该颜色所处的位置,取值范围为[0, 1.0],设置的值小于0时,按0处理,设置的值大于1.0时,按1.0处理。为了实现多个颜色渐变效果,多个数组中的number类型参数应递增设置。如果后一个数组中的number类型参数小于前一个数组的number类型参数,将按照等于前一个数组number值处理。
Row() {}.width(20).height(150).borderRadius(10)
// 线性渐变
.linearGradient({
// angle:135, //起始角度180
colors: [
['#66ccff', 0.25],
['#9900ff', 0.3],
[Color.Blue, 0.4],
['#66ff66', 0.5],
[Color.Green, 0.6],
[Color.Yellow, 0.7],
[Color.Orange, 0.8],
[Color.Red, 0.9],
['#66ccff', 1]
],
// 如果设置了angle direction不生效
// direction:GradientDirection.Left // 往左渐变
// direction:GradientDirection.LeftTop, // 向左上渐变
// repeating属性存在时,则颜色数组中的最大值不应该出现1.
repeating:true, //默认false 不重复着色。 true,从数组中重头渐变一下
})
sweepGradient角度渐变
sweepGradient(options: Optional<SweepGradientOptions>): T
| SweepGradientOptions | ||
|---|---|---|
| center | 必选 | 为角度渐变的中心点,即相对于当前组件左上角的坐标。 |
| colors | 必选 | 指定渐变色颜色和其对应的百分比位置的数组 |
| start | 角度渐变的起点。 默认值:0。 | |
| end | 角度渐变的终点。 默认值:0。 | |
| rotation | 角度渐变的旋转角度。默认值:0。 | |
| repeating | 为渐变的颜色重复着色。 |
- 渐变角度为0~360,若渐变角度超出这一范围,则仅绘制纯色。
- 若colors数组中最后一个元素的百分比位置小于1,且不重复着色,则从该处向后一直都是该纯色。
- 若repeating参数为true,结束色的百分比位置小于1,则结束角度和起始角度之间的角度差会产生一定的压缩。
// 角度渐变
Row(){}.width(100).height(100)
.borderRadius(50)
.sweepGradient({
center:[25,50],
// 角度的起始和终止点是可选的,。但是如果没写,没效果
start:0,
end:360,
colors: [
['#66ccff', 0.25],
['#9900ff', 0.3],
[Color.Blue, 0.4],
['#66ff66', 0.5],
[Color.Green, 0.6],
[Color.Yellow, 0.7],
[Color.Orange, 0.8],
[Color.Red, 0.9],
['#66ccff', 1]
],
repeating:true, // 这个属性跟颜色数组是否到1有关系
rotation:60 // 起始角度不从0开始了。而是可以指定从多少度开始渐变了
})
radialGradient径向渐变
radialGradient(options: Optional<RadialGradientOptions>): T
| RadialGradientOptions | ||
|---|---|---|
| center | 必选 | 径向渐变的中心点,即相对于当前组件左上角的坐标。 |
| radius | 必选 | 径向渐变的半径。 |
| colors | 必选 | 指定渐变色颜色和其对应的百分比位置的数组 |
| repeating | 为渐变的颜色重复着色。 |
// 径向渐变
Row(){}.width('100%').height(250).backgroundColor('#ccc')
.radialGradient({
center:['50%',280],
radius:'100%', //径向渐变的尺寸
colors: [
['#66ccff', 0.25],
['#9900ff', 0.3],
[Color.Blue, 0.4],
['#66ff66', 0.5],
[Color.Green, 0.6],
[Color.Yellow, 0.7],
[Color.Orange, 0.8],
[Color.Red, 0.9],
['#66ccff', 1]
],
// repeating:true
})
| 显示隐藏类属性 | |
|---|---|
visibility: | 设置组件的是否可见: visibility.Hideden:虽然隐藏了,但是会占位 visibility.None:隐藏,但是不占位 visibility.Visible:显示 |
opacity: | 设置组件的透明度 |
displayPriority: | 设置组件的显示优先级。父容器裁剪时,会隐藏掉优先级最低的子元素。 |
zlndex: | 设置组件的Z轴堆叠顺序 |
私有属性
Text
| 属性 | 效果 |
|---|---|
| fontSize | 设置文字的大小 |
| fontColor | 设置文字的颜色 |
| fontWeight | 设置文字的粗细 |
| letterSpacing | 设置每个文字之间的间距 |
| textAlign | 设置文字的对齐方式 |
| maxLines | 设置文字的展示最大行数,超出隐藏 |
| textOverflow | 设置文字超出的样式 |
| lineHeight | 设置文字的行间 距 |
image
| 属性 | 效果 |
|---|---|
| alt | 设置图片加载时的占位图 |
| objectFit | 设置图片的填充模式 |
| fillColor | 设置SVG图片的填充色 |
事件
组件事件间的区别:不同的ArkUI系统组件在使用时会产生不同的交互,比如:文本输入框可以输入内容、列表可以滚动等,但是不同的组件也可以有相同的交互,比如:任何系统组件都可以点击
组件事件的分类:和属性一样,组件的事件也分为了通用事件和私有事件。所有组件都能添加的叫做通用事件。每个组件特有的事件叫做私有事件。
通用事件
onClick:点击
-
触发条件:手指按下后抬起,仅支持单指
-
事件对象:可以获取点击的位置
Button('按钮1')
.onClick(() => {
// 弹窗方式1
// promptAction.openToast({
// message:'点击事件'
// })
// 弹窗方式1
this.getUIContext().getPromptAction().showToast({
message: '点击事件',
duration: 4000
})
})
onFocus、onBlur焦点
-
触发条件:当用户使用键盘、电视遥控器、车机摇杆/旋钮等非指向性输入设备与应用程序进行间接交互时,焦点在组件间移动时触发。
-
限制:
- 存在默认交互逻辑的组件例如
Button、Textlnput等,默认即可获焦 - 默认无法获焦的组件(例如信息展示类组件中的文本,图片等组件)需要设置
focusable属性为true才可触发
- 存在默认交互逻辑的组件例如
-
事件对象:无
// 多行输入框
TextArea()
.onFocus(() => {
this.getUIContext().getPromptAction().showToast({
message: '输入框获取焦点了---拉起键盘'
})
})
.onBlur(() => {
this.getUIContext().getPromptAction().showToast({
message: '输入框获取失去焦点了---隐藏键盘'
})
})
Text('文本1')
// 默认不会获取焦点
.focusable(true)
onTouch:触摸
-
触发条件:手指按下后开始触发,支持多指。
-
事件对象:可以捕获按下、移动、抬起三种状态等
Stack() {
Image($r('app.media.gege'))
.width(200)
.focusable(true) // 获焦能力
.focusOnTouch(true) // 点击获焦能力
// 触摸
.onTouch((e: TouchEvent) => {
if (e.type === TouchType.Down) {
this.getUIContext().getPromptAction().showToast({
message: '按下--'
})
}
if (e.type === TouchType.Up) {
this.getUIContext().getPromptAction().showToast({
message: '抬起--'
})
}
if (e.type === TouchType.Move) {
this.getUIContext().getPromptAction().showToast({
message: '移动-- '
})
}
// 触摸的过程中 优先级>Move
if (e.touches) {
this.getUIContext().getPromptAction().showToast({
message: `touches--${e.touches[0].x}----${e.touches[0].y}`
})
this.xVal = e.touches[0].x
this.yVal = e.touches[0].y
}
})
Row() {
}
.width(50)
.aspectRatio(1)
.backgroundColor('#ff2ad68b')
.borderRadius(25)
.position({
x: this.xVal -25,
y: this.yVal -25
})
}
// 裁剪
.clip(true)
onAreaChange:组件区域变化事件
-
触发条件:组件大小、位置变化时触发。
-
事件对象:可以获取变化前、后的大小和位置状态
// 多行输入框
TextArea()
.onFocus(() => {
this.getUIContext().getPromptAction().showToast({
message: '输入框获取焦点了---拉起键盘'
})
})
.onBlur(() => {
this.getUIContext().getPromptAction().showToast({
message: '输入框获取失去焦点了---隐藏键盘'
})
})
.onAreaChange(() => {
// 组件绘制的时候会瞬间触发一次
// 组件大小、位置变化时触发。
this.getUIContext().getPromptAction().showToast({
message: `TextArea触发了---onAreaChange ${e.position.x}`
})
})
私有事件
| 组件 | 事件类型 | 触发条件 | 事件对象 |
|---|---|---|---|
Text | onCopy | 长按文本内部区域弹出剪贴板后,点击复制按妞。(需要使用属性方法copyOption来开启复制,否则长按是没有反应的) | 复制的文本内容 |
Image | onError | 图片加载异常时触发 | 加载异常时返回的报错信息Image('https://xxx.jpg') |
TextInput | onChange | 输入内容发生变化时 | 文本框正式上屏的文本内容 |
CheckBox | onChange | 选中状态发生变化时触发 | 选中的状态 |
Toggle | onChange | 开关状态发生变化时触发 | 开启或关闭的状态 |
Slider | onChange | 滑块滑动时触发 | 当前选中的值 |
List | onReachEnd | 能滚动时,列表到达末尾位置时触发。回弹触底触发第二次。不满一屏时也会触发一次。 | 无事件对象 |
List | onReachStart | 同上,触顶 | 无事件对象 |
// 组件私有属性
Text('长按后选择复制')
// 需要开启复制
.copyOption(CopyOptions.InApp)
// 点击复制后触发
.onCopy((e) => {
// 使用轻吐司效果进行展示
this.getUIContext().getPromptAction().openToast({
message: `复制成功:${e}`
})
})
Image('https://xxx.jpg')
// 图片加载失败后触发
.onError((e) => {
this.getUIContext().getPromptAction().openToast({
message: `图片加载失败:${e.message}`
})
})
TextInput()
.onChange((e) => {
this.getUIContext().getPromptAction().openToast({
message: `当前输入的内容为:${e}`
})
})
Checkbox()
.onChange((e) => {
this.getUIContext().getPromptAction().openToast({
message: `当前选中的状态为:${e}`
})
})
Toggle({ isOn: false, type: ToggleType.Switch })
.onChange((e) => {
this.getUIContext().getPromptAction().openToast({
message: `当前开关的状态为:${e}`
})
})
Slider()
.onChange((e) => {
this.getUIContext().getPromptAction().openToast({
message: `当前滑动到的位置:${e}`
})
})
List({ space: 10 }) {
ListItem() {
Row()
.width('100%')
.height('200')
.backgroundColor('#ff9575e3')
}
ListItem() {
Row()
.width('100%')
.height('200')
.backgroundColor('#ff9575e3')
}
ListItem() {
Row()
.width('100%')
.height('200')
.backgroundColor('#ff9575e3')
}
ListItem() {
Row()
.width('100%')
.height('200')
.backgroundColor('#ff9575e3')
}
ListItem() {
Row()
.width('100%')
.height('200')
.backgroundColor('#ff9575e3')
}
ListItem() {
Row()
.width('100%')
.height('200')
.backgroundColor('#ff9575e3')
}
}
.layoutWeight(1)
// 设置边缘滑动效果
.edgeEffect(EdgeEffect.None) //关闭回弹,避免触底两次。方便在一些触底加载业务的时候使用。避免执行两次业务
.backgroundColor('#ffcfddd9')
.onReachEnd(() => {
this.getUIContext().getPromptAction().openToast({
message: `触底了`
})
})
.onReachStart(() => {
this.getUIContext().getPromptAction().openToast({
message: `触顶了`
})
})
自定义组件
- 为什么要自定义组件
ArkUI提供了很多功能强大的系统组件,能够帮助我们快速实现一些常见的功能和UI效果。但是各个业务领域一般都会有一些特殊的定制需求,当系统组件不能够完全契合时,就需要自定义组件
- 什么是自定义组件?
自定义组件就是通过开发者组合系统组件和封装业务逻辑形成一个新的组件,系统组件是系统定义的组件,自定义组件是开发者定义的组件
- 如何进行自定义组件?
- 创建自定义组件:按照语法规范定义一个新的组件,可以反复使用。创建自定义组件也叫做封装组件或声明组件,每个ets文件都可以声明多个自定义组件,组件名遵循大驼峰规范且唯一
- 使用自定义组件:与像使用系统组件一样,使用
组件名()
自定义组件的导入及导出
组件所在的文件是 可以直接使用这个组件的,但是由于自定义组件可以复用的便利性,我们也可以将自己的自定义的组件分享给自己需要开发的其他页面和组件使用,也可以分享给同项目的成员使用。当然,我们也可以使用其他项目成员分享组件来开发自己的页面,这个就需要对组件进行导入导出了。
-
默认导出语法:
export default 自定义名称。导出后,可以在当前模块内任意位置导入该组件 -
默认导入语法:
import 自定义名称 from 组件路径。导入后可以在当前文件任意位置使用该组件
在自定义组件中可以使用
@Preview进行预览
多个组件导入导出
组件是构建页面的基本单元,我们通常会定义很多组件,也会引用很多的组件,这种多组件的导入导出也称为命名导入和命名导出
-
命名导出语法:需要导出组件的
struct前面添加export -
命名导入语法:
import {组件1,组件2,组件3...} from 组件路径
自定义组件属性
- 什么是自定义组件的属性?
在自定义组件时,组件内声明的变量,这个变量就可以称为自定义组件的属性
- 为什么要自定义组件的属性?
我们在自定义组件时,可以将使用到的系统组件参数、属性或事件定义为组件属性,从而实现使用自定义组件像使用组通组件一样灵活多变。 比如:系统组件Text的文字颜色可以修改,如果我们自定义组件用了Text,自定义组件也可以实现文字颜色的修改
-
组件传值
在使用自定义组件时传递参数也叫做组件传值,传递的值会覆盖自定义组件中定义的属性值(也可以传递函数),自定义组件默认支持通用属性和通用事件**(在调用处进行使用)**。
-
如何设计及使用自定义组件属性
书写位置:在struct内,build外定义属性,类似于变量数据。语法:属性名:类型=初始值。自定义组件定义属性并会不影响组件的使用与效果,该属性通过this.属性名使用在组件的属性方法时,才会发挥作用。

组件扩展
@Styles:定义组件重用样式
如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续
方便维护,可以提炼公共样式进行复用,也叫做定义组件重用样式。
- 仅支持通用属性和通用事件
- 可以定义在组件内,也可以定义在全局,但不支持导出,只能在当前文件内使用
- 组件内与全局的重用样式同时使用时组件内优先生效
组件内定义重 用样式:
- 在struct内,build外,定义一个函数
- 对这个函数使用@Styles装饰器修饰
- 函数内书写提炼的重复样式属性
- 对需要提炼的组件使用函数名的属性
全局定义重用样式:
- 组件外使用function关键字定义一个函数
- 对这个函数使用@Styles装饰器修饰
- 函数内书写提炼的重复样式属性
- 对需要提炼的组件使用函数名的属性
不支持导出,仅在当前组件内使用。
@Extends:
与定义重用样式相同的时都是用来提炼样式的。
但扩展组件样式用于指定某个组件进行样式扩展,即支持通用属性、通用事件,也支持私有属性和私有事件,同时支持参数传递
定义扩展组件样式说明:
- 扩展指定组件,只有被扩展的组件才能使用
- 仅支持在全局定义,同样不支持导出
- 扩展组件样式支持传递参数
语法说明:
- 组件外使用function关键字定义一个函数
- 对这个函数使用@Extend()装饰器修饰
()内写入需要扩展的组件名- 函数内书写提炼的重复的属性或事件
- 不同的属性或事件可以通过参数接收
- 对需要提炼的组件使用函数名的属性
多态样式
组件的内部状态,ArkUI提供了一下五种状态:normal正常态、focused获焦态、pressed按压态、disabled禁用态、selected选中
态
状态管理
V1版本
- @State装饰器:组件内状态
- @Prop装饰器:父子单向同步
- @Link装饰器:父子双向同步
- @Provide装饰器和@Consume装饰器:与后代组件双向同步
- @Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化
V2版本
渲染控制
条件渲染
if/else:条件渲染
循环渲染
ForEach:循环渲染
数据懒加载
ForEach适用的场景:数据源不变的列表渲染。数据懒加载适用的场景:长列表的优化渲染。
优化原理:从数据源中按需迭代数据,每次迭代时根据滚动容器可视区域按需创建相应组件,当组件滑出可视区域外时,框架会销毁并回
收组件以降低内存占用。
数据懒加载语法:LazyForEach( 数据源,结构体生成函数 [,键值生成函数 ] )
实现步骤:
- 实现IDataSource管理数据源的监听器和更新
- 定义数 据源
- 使用LazyForEach渲染数据源
//src/main/ets/utils/LazyForEachType.ets
export class LazyForEachType<T> implements IDataSource {
data: T[] = []
listeners: DataChangeListener[] = []
totalCount(): number {
return this.data.length
}
getData(index: number): T {
return this.data[index]
}
registerDataChangeListener(listener: DataChangeListener): void {
// 如果当前监听器数组中找不到这个监听器。那就注册进数组
if (this.listeners.indexOf(listener)===-1){
this.listeners.push(listener)
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
// 如果监听器数组中有这个监听器,就卸载
const index = this.listeners.indexOf(listener)
if (index>-1) {
this.listeners.splice(index,1)
}
}
// 添加数据源的方法
pushData(data:T[]){
this.data.push(...data)
// 添加完数据源让视图更新
this.listeners.forEach((listener) => {
listener.onDataReloaded() //刷新数据
})
}
}