
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
水之积也不厚,则其负大舟也无力
前言:写这篇文章的目的性,是让新手了解几个装饰器的作用,知道如何更加的使得代码模块化,复用性更高,提升代码的阅读效率。
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
Api9下的注册方式
UI都是通过@Component声明来修饰,如下
于是我们可以用@Preview来预览效果
@Builder装饰器定义了一个如何==渲染自定义组件的方法==,语法和作用和build函数一致。
通过@Builder装饰器可以在一个==自定义组件内==快速生成多个布局内容
这样的好处就是可以减少大量重复的代码,还能逻辑统一,一处修改多UI生效
@Entry
@Component
struct Index {
@State message: string = 'Builder演示'
@State isA: boolean= false
@State isB: boolean= false
@State isC: boolean= false
@State isD: boolean= false
/* 方法内有组件,需要加@Builder装饰 */
@Builder myBuilder(str: string, state: boolean, click: () => void) {
Row() {
Text(str + ":" + state)
.fontSize(24).margin({ right: 20 })
Button('开关').fontSize(24).onClick(() => {
click()
})
}
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(24)
.fontWeight(FontWeight.Bold).margin({ bottom: 20 })
this.myBuilder('A', this.isA, () => {
this.isA = !this.isA
})
this.myBuilder('B', this.isB, () => {
this.isB = !this.isB
})
this.myBuilder('C', this.isC, () => {
this.isC = !this.isC
})
this.myBuilder('D', this.isD, () => {
this.isD = !this.isD
})
}
.width('100%')
}
.height('100%')
}
}
==对内置组件进行二次封装==
@Extend装饰器不能用在自定义组件struct定义框内
模拟器测试报错,理论上是可以支持的
这样的优点可以减少对内置组件的重复设置,可以封装在一个方法内
@Extend(Text) function fancy (size: number, color: ResourceColor) {
.fontSize(size)
.fontColor(color)
}
@Entry
@Component
struct Index {
@State message: string = 'Extend演示'
build() {
Column() {
Text(this.message)
.fancy(24, Color.Blue)
}
}
}
@CustomDialog
struct CustomDialogExample {
controller: CustomDialogController
cancel: () => void
confirm: () => void
build() {
Column() {
Text('自定义弹窗').fontSize(20).margin({ top: 10, bottom: 10 })
Image($r('app.media.icon')).width(80).height(80)
Text('你确认要这样选择吗?').fontSize(16).margin({ top: 10, bottom: 10 })
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('否')
.onClick(() => {
this.controller.close()
this.cancel()
}).backgroundColor(0xffffff).fontColor(Color.Black)
Button('是')
.onClick(() => {
this.controller.close()
this.confirm()
}).backgroundColor(0xffffff).fontColor(Color.Red)
}.margin({ bottom: 10 })
}
}
}
@Entry
@Component
struct CustomDialogUser {
@State text: string= ""
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({ cancel: this.onCancel, confirm: this.onAccept }),
cancel: this.existApp,
autoCancel: true
})
onCancel() {
console.info('Callback when the first button is clicked')
this.text = '用户点击了取消'
}
onAccept() {
this.text = '用户点击了确认'
console.info('Callback when the second button is clicked')
}
existApp() {
console.info('Click the callback in the blank area')
this.text = '用户点击了空白处'
}
build() {
Column() {
Text(this.text).fontSize(24).margin({ top: 10 })
Button('打开弹窗').fontSize(24)
.onClick(() => {
this.dialogController.open()
})
}.width('100%').margin({ top: 10 })
}
}
注意:从效果看 @State修饰的变量,从@CustomDialog修饰的CustomDialogExample类,回调了该方法,但是它没有重新使得build刷新,
原因不明(==评论区有答案==)
可以在局部样式相同,局部样式不同是复用
@Component
struct CustomContainer {
title: string;
subTitle: string;
@BuilderParam content: () => any
build() {
Column() {
Text(this.title).fontSize(24).fontColor('#FF0000')
Text(this.subTitle).fontSize(18).fontColor('#0D9FFB')
this.content()
}
}
}
@Entry
@Component
export struct MainPage {
build() {
Column() {
Text('@BuilderParam演示')
.fontSize(24).margin({ top: 20 })
Column() {
CustomContainer({ title: '标题1', subTitle: '内容1' }) {
Row() {
Text('图文结合').fontSize(18)
Image($r('app.media.app_icon')).width(30).height(30)
}
}
}.margin({ top: 20 })
Column() {
CustomContainer({ title: '标题2', subTitle: '内容2' }) {
Row() {
Text('其他样式').fontSize(18)
Button('点击').fontSize(20)
}
}
}.margin({ top: 20 })
}
.height('100%')
.width('100%')
}
}
@Styles装饰的方法不能带参数
组件内@Styles装饰的方法可以有多个
多个相同属性可以利用此装饰器封装
@Entry
@Component
struct Stylesdemo {
@State message: string = 'Hello World'
@Styles backgroundRed(){
.backgroundColor(Color.Red)
}
@Styles size100(){
.width(100)
.height(100)
}
build() {
Row() {
Column() {
Text(this.message)
.backgroundRed()
.fontSize(50)
.fontWeight(FontWeight.Bold)
Image($r('app.media.app_icon')).size100()
}
.width('100%')
}
.height('100%')
}
}