ArkTS的 UI范式装饰器 和 状态管理装饰器
1 UI范式装饰器
1.1 @Styles:组件样式的重用
对于不同组件的相同样式、事件统一抽取,然后复用,提高代码简洁性和方便后续维护。
@Styles分为全局定义和局部定义
定义为全局时,在方法名前添加function关键字
//定义全局的@Styles封装样式
@Styles
function globalFancy() {
.width(200)
.height(100)
.backgroundColor(Color.Pink)
}
@Entry
@Component
struct Index {
@State bgColor: ResourceColor = Color.Pink
//定义组件内的@Styles封装样式
@Styles
fancy(){
.width(180)
.height(60)
.backgroundColor(this.bgColor)
.onClick(() => {
this.bgColor = Color.Red
})
}
build() {
Column({ space: 10 }) {
//使用全局@Styles
Text("全局@Styles")
.fontSize(20)
.globalFancy()//通过 .函数名() 方式复用
//使用组件内@Styles
Text("组件内@Styles")
.fontSize(20)
.fancy()
}
.width("100%")
}
}
说明:
b.组件内@Styles的优先级高于全局@Styles
c.函数不支持传参!!
1.2 @Extend:特定组件样式的重用
对于同一组件的样式、事件,统一抽取,减少代码量,增强可读性。
@Extend只有全局定义
@Extend(Text)
function fancy(fSize: number, fColor: ResourceColor, bgColor: ResourceColor) {
.fontSize(fSize)
.fontColor(fColor)
.backgroundColor(bgColor)
}
@Entry
@Component
struct Index {
build() {
Column() {
Text("@Extend重用")
.fancy(20, Color.Blue, Color.Red)
Text("@Extend重用")
.fancy(30, Color.White, Color.Green)
Text("@Extend重用")
.fancy(40, Color.Red, Color.Blue)
}.width("100%")
}
}
说明:
a.使用@Extend()时,在括号里加上要修饰的组件
b.只支持原生组件样式扩展
c.函数支持传参
1.3 @Builder:UI结构的重用
将重复使用的UI元素抽象成一个方法,在build方法里调用。@Builder装饰的函数也称为“自定义构建函数”。
@Builder分为全局定义和局部定义
语法:
//1 全局定义
@Builder globalBuilder(){}
@Entry
@Component
struct Index {
//2 局部定义
@Builder MyBuilder(){}
build() {
Column(){
//1
globalBuilder()
//2
this.MyBuilder()
}
}
}
说明:
a.可传递参数
b.局部定义通过 .函数名() 方式复用
c.静态页面@Builder复用可传递多个参数,但如果要动态刷新页面,参数传递会有一些限制:
1.3.1 传参规则
-
参数的类型必须与参数声明的类型一致,不允许
undefined、null和返回undefined、null的表达式。 -
在
@Builder修饰的函数内部,不允许改变参数值。 -
@Builder内UI语法遵循UI语法规则 -
@Builder通过按引用传递的方式传入参数,才会触发动态渲染UI,并且参数只能是一个。 -
@Builder如果传入的参数是两个或两个以上,不会触发动态渲染UI。 -
@Builder传入的参数中同时包含按值传递和按引用传递两种方式,不会触发动态渲染UI。 -
@Builder的参数必须按照对象字面量的形式,把所需要的属性一一传入,才会触发动态渲染UI。
tips:
对象字面量:一种创建对象的简便语法。它通过一对花括号 {} 包含一组以逗号分隔的键值对,每个键值对由一个属性名和一个属性值组成。语法示例如下:
const obj = {
name: "Alice",
age: 25,
isStudent: false
}
1.3.2 传参方式
按值传递
调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。
@Builder
function commonBuilder(wid: number) {
Column() {
Image($r('app.media.startIcon'))
.width(wid)
}
}
@Entry
@Component
struct Index {
@State wid: number = 50
build() {
Column() {
commonBuilder(this.wid)
Button("刷新UI")
.onClick(() => {
this.wid = 100
})
}.width("100%")
}
}
按引用传递
按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。
class CL {
param1: number = 10
}
@Builder
function commonBuilder(params: CL) {
Column() {
Image($r('app.media.startIcon'))
.width(params.param1)
}
}
@Entry
@Component
struct Index {
@State wid: number = 50
build() {
Column() {
commonBuilder({ param1: this.wid })
Button("刷新UI")
.onClick(() => {
this.wid = 100
})
}.width("100%")
}
}
2 状态管理装饰器
2.1 @State-管理组件拥有的状态-组件内状态
用@State装饰的变量,称为状态变量。当状态变量发生改变时,UI会自动刷新。
说明:
a.被@State装饰的变量必须指定类型和初始化
b.@State装饰的变量生命周期与其所属自定义组件的生命周期相同
c.@State装饰的变量,是私有的,只能从组件内部访问
后续会继续更新装饰器相关的知识。