样式&结构重用介绍

68 阅读3分钟

作用:提升编码效率,减少重复代码,提升代码可读性。

  1. @Extends:扩展组件(样式、事件)
  2. @Styles: 抽取通用属性、事件
  3. @Builder:自定义构建函数(结构、样式、事件)

1.@Extend

语法:

// 1. 定义在全局
@Extend(组件名) 
function functionName(参数1....) {
  .属性()
  .事件(()=>{})
}


// 2. 使用
组件名(){}
  .functionName(参数1...)

举例:

@Entry
@Component
struct Extends_demo {
 @State message: string = '样式&结构重复使用'

 build() {
   Column({ space: 10 }) {
     Text(this.message)
       .fontSize(30)
     Swiper() {
       Text('0')
         .textExtend(Color.Red, '轮播图 1')
       Text('1')
         .textExtend(Color.Green, '轮播图 2')
       Text('2')
         .textExtend(Color.Blue, '轮播图 3')
     }
     .width('100%')
     .height(160)
   }
   .width('100%')
   .height('100%')
 }
}


//这里对Text进行拓展,只能用在Text组件上
@Extend(Text)
function textExtend(backgroudColor: ResourceColor, info: string) {
 .textAlign(TextAlign.Center)
 .backgroundColor(backgroudColor)
 .fontColor(Color.White)
 .fontSize(30)
 .onClick(() => {
   AlertDialog.show({
     message: info
   })
 })
}

//Text能.出来属性都可以写在Extend里面

注意:Extend只有全局定义写法,可以进行传参数,它是针对于某一个组件进行拓展,如对Text组件进行拓展后,在build函数里面只能在Text的组件上面使用,如果其他组件也需要,则需要重新定义一个自己的拓展

2.@Styles

不同于@Extend 用来给某个组件扩展,@Styles 不仅可以对单个组件进行拓展,还是对多个组件进行拓展,但是不能是特殊属性,只能是通用属性,不能进行传参,如对column调用后,也可以对相同属性的row进行调用。

语法:

// 全局定义
@Styles function functionName() {
 .通用属性()
 .通用事件(()=>{})
}


@Component
struct FancyUse {


 // 在组件内定义
 @Styles fancy() {
     .通用属性()
     .通用事件(()=>{})
 }
}


// 使用
组件().fancy()
组件().functionName()

举例:

//这里是全局定义
@Styles
function globalSize() {
.width(100)
.height(100)
}


@Entry
@Component
struct Day01_03_Styles {
@State message: string = '@styles';
@State bgColor: ResourceColor = Color.Gray

build() {
  Column({ space: 10 }) {
    Text(this.message)
      .width(100)
      .height(100)
      .backgroundColor(this.bgColor)
      .onClick(() => {
        this.bgColor = Color.Orange
      })

    Column() {
    }//都是对column的相关属性设置进行调用,只能是通用属性。
    
    //全局调用
    .globalSize()
    
    //局部调用
    .sizeAndColorFancy()
  

    Button('按钮')
      .width(100)
      .height(100)
      .backgroundColor(this.bgColor)
      .onClick(() => {
        this.bgColor = Color.Orange
      })
  }
  .width('100%')
  .height('100%')
}


//这里是局部定义
@Styles
sizeAndColorFancy() {
  .backgroundColor(this.bgColor)
  .onClick(() => {
    this.bgColor = Color.Orange
  })
}
}

注意:不管是全局定义还是局部定义,他们在build里面都是.出来的,而且在结构体里面只能写通用属性,不能写特殊属性,如fontcolorl,而且@Styles不能进行传参数

3.@Builder

如果连结构都需要进行抽取,则使用@Builder,它可以对任何函数进行封装处理,也是在开发中常用的一个函数

语法:

//全局 构建函数
@Builder function MyGlobalBuilderFunction(param1,param2...) {
// 结构、属性、事件放这里
}
// 使用
MyGlobalBuilderFunction(param1,param2...)

//组件内 构建函数
@Builder MyBuilderFunction( param1,param2...) {
// 结构、属性、事件放这里
}
// 使用,注意:这里进行调用的时候要使用this.出来
this.MyBuilderFunction(param1,param2...)

举例:

//进行全局定义,可以进行传参
@Builder
function GlobalTextItem(title: string) {
Text(title)
  .fontSize(30)
  .onClick(() => {
    // 逻辑略
  })
}

@Entry
@Component
struct Day01_04_Builder {
@State message: string = '@Builder';

build() {
  Column({ space: 20 }) {
    // 使用全局 Builder
    GlobalTextItem('你好')
    
    // 使用本地 Builder
    this.LocalTextItem('西兰花炒蛋')
  }
  .width('100%')
  .height('100%')
}


//局部定义
//这里是将text整个组件以及相关的属性进行封装,以及可以将多个组件和属性进行封装
//不像@Extend只能将text的相关属性进行封装
//以及不像@Style只能对组件的通用属性进行封装
@Builder
LocalTextItem(title: string) {
  Text(title)
    .fontSize(30)
    .onClick(() => {
      // 逻辑略
    })
}
}

注意:唯独它是需要使用this.出来的,另外两个是不需要的

4.对比

image.png