当前位置:   article > 正文

HarmonyOS系统开发ArkTS常用组件编程技巧_组件内的styles方法只能在当前

组件内的styles方法只能在当前

目录

样式复用

@Styles方法

@Extend方法


        组件编程在使用过程中有很多技巧,在这里分享样式复用技巧和UI结构复用技巧。

样式复用

我们观察下面的代码,在代码中很多重复行的代码,如:

    Image 的  .width(30).height(30) 是重复的
    Button的  .fontSize(25).width(150).height(65).backgroundColor(Color.Green)是重复的
    Text  的  .fontSize(20).fontColor(Color.White).fontWeight(500) 是重复的
  1. @Entry
  2. @Component
  3. struct customStyle {
  4. @State isOn: boolean = false;
  5. @State isDel: boolean = false;
  6. build() {
  7. Column({ space: 10 }) {
  8. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  9. Row({ space: 10 }) {
  10. Image($r('app.media.icon_new_folder'))
  11. .width(30)
  12. .height(30)
  13. Text('新建文件')
  14. .fontSize(20)
  15. .fontColor(Color.White)
  16. .fontWeight(500)
  17. }
  18. }
  19. .fontSize(25)
  20. .width(150)
  21. .height(65)
  22. .backgroundColor(Color.Green)
  23. .onClick(() => {
  24. console.log('我准备开始建立文件夹');
  25. })
  26. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  27. Row({ space: 10 }) {
  28. Image($r('app.media.icon_new_folder'))
  29. .width(30)
  30. .height(30)
  31. Text('新建文件')
  32. .fontSize(20)
  33. .fontColor(Color.White)
  34. .fontWeight(500)
  35. }
  36. }
  37. .fontSize(25)
  38. .width(150)
  39. .height(65)
  40. .backgroundColor(Color.Green)
  41. .onClick(() => {
  42. console.log('我准备开始建立文件夹');
  43. })
  44. }
  45. .width('100%')
  46. .height("100%")
  47. .justifyContent(FlexAlign.Center)
  48. }
  49. }
  50. @Extend(Image) function consumeImgStyle() {
  51. .width(30)
  52. .height(30)
  53. }
  54. @Extend(Button) function consumeButtonStyle() {
  55. .fontSize(25)
  56. .width(150)
  57. .height(65)
  58. }
  59. @Extend(Text) function consumeBTextStyle() {
  60. .fontSize(20)
  61. .fontColor(Color.White)
  62. .fontWeight(500)
  63. }

        当多个组件具有相同的样式时,若每个组件都单独设置,将会有大量的重复代码。为避免重复代码,开发者可使用@Styles或者@Extend装饰器将多条样式设置提炼成一个方法,然后直接在各组件声明的位置进行调用,这样就能完成样式的复用。

@Styles方法

      @Styles方法可定义在组件内或者全局。

  • 1. 组件内定义的@Styles方法只能在当前组件中使用,全局的@Styles方法目前只允许在当前的.ets文件中使用
  • 2. 组件内定义@Styles方法时不需要使用function关键字,全局的@Styles方法需要使用function关键字
  • 3. @Styles方法中只能包含通用属性方法和通用事件方法,例如在上面的代码中 fontSize(20).fontColor(Color.White).fontWeight(500)也是重复的,但这不是通用属性。可以定义的只能是通用属性。
  • 4. @Styles方法不支持参数
  • 5. @Styles方法可以用在任意类型的组件上。注意下面的@Extend则是使用在定制化组件上。

       将上面重复的样式代码分别提取到各自定义的@Style方法中,直接使用@Style方法
定义格式如下。

  1. @Styles定义在Struct结构体内部
  2. ===============================================================================
  3. @Styles consumeImgStyle(){
  4. .width(30)
  5. .height(30)
  6. }
  7. @Styles consumeButtonStyle(){
  8. .width(150)
  9. .height(65)
  10. .backgroundColor(Color.Green)
  11. }
  12. @Styles定义在同一个ets文件中的Struct结构体外部,必须加上 function 关键字
  13. ===============================================================================
  14. @Styles function globalConsumeImgStyle() {
  15. .width(30)
  16. .height(30)
  17. }
  18. @Styles function globalConsumeButtonStyle() {
  19. .width(150)
  20. .height(65)
  21. .backgroundColor(Color.Green)
  22. }

        将重复样式代码提取之后,直接使用提取后的方法,使用@Styles方法之后代码。

  1. @Entry
  2. @Component
  3. struct customStyle {
  4. @State isOn: boolean = false;
  5. @State isDel: boolean = false;
  6. build() {
  7. Column({ space: 10 }) {
  8. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  9. Row({ space: 10 }) {
  10. Image($r('app.media.icon_delete'))
  11. .consumeImgStyle()
  12. Text('删除文件')
  13. .fontSize(20)
  14. .fontColor(Color.White)
  15. .fontWeight(500)
  16. }
  17. }
  18. .fontSize(25)
  19. .width(150)
  20. .height(65)
  21. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  22. Row({ space: 10 }) {
  23. Image($r('app.media.icon_new_folder'))
  24. .consumeImgStyle()
  25. Text('新建文件')
  26. .fontSize(20)
  27. .fontColor(Color.White)
  28. .fontWeight(500)
  29. }
  30. }
  31. .consumeButtonStyle()
  32. .fontSize(25)
  33. .onClick(() => {
  34. console.log('我准备开始建立文件夹');
  35. })
  36. }
  37. .width('100%')
  38. .height("100%")
  39. .justifyContent(FlexAlign.Center)
  40. }
  41. @Styles consumeImgStyle(){
  42. .width(30)
  43. .height(30)
  44. }
  45. @Styles consumeButtonStyle(){
  46. .width(150)
  47. .height(65)
  48. .backgroundColor(Color.Green)
  49. }
  50. }
  51. 定义全局使用的@Styles方法需要加 function
  52. ======================================================
  53. @Styles function globalConsumeImgStyle() {
  54. .width(30)
  55. .height(30)
  56. }
  57. @Styles function globalConsumeButtonStyle() {
  58. .width(150)
  59. .height(65)
  60. .backgroundColor(Color.Green)
  61. }

@Extend方法

     @Extend装饰的方法同样可用于组件样式的复用,与@Styles不同的是:

  • @Extend方法只能定义在全局,使用范围目前只限于当前的.ets文件
  • @Extend方法只能用于指定类型的组件,如Button组件
  • @Extend方法可包含指定组件的专有属性方法和专有事件方法。
  • @Extend方法支持参数传递

       重复的代码

        Image 的  .width(30).height(30) 是重复的
        Button的  .fontSize(25).width(150).height(65) .backgroundColor(Color.Green)是重复的
        Text  的  .fontSize(20).fontColor(Color.White).fontWeight(500)是重复的

        将上面重复的样式代码分别提取到各自定义的@Extend方法中,直接使用@Extend方法
定义格式如下。

  1. @Extend(Image) function consumeImgStyle() {
  2. .width(30)
  3. .height(30)
  4. }
  5. @Extend(Button) function consumeButtonStyle(color: Color) {
  6. .fontSize(25)
  7. .width(150)
  8. .height(65)
  9. .backgroundColor(color)
  10. }
  11. @Extend(Text) function consumeTextStyle(color: Color, size: number, weight: number) {
  12. .fontSize(size)
  13. .fontColor(color)
  14. .fontWeight(weight)
  15. }

    将重复样式代码提取之后,直接使用提取后的方法,使用@Extend方法之后代码。

  1. @Entry
  2. @Component
  3. struct customStyle {
  4. @State isOn: boolean = false;
  5. @State isDel: boolean = false;
  6. build() {
  7. Column({ space: 10 }) {
  8. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  9. Row({ space: 10 }) {
  10. Image($r('app.media.icon_new_folder'))
  11. .consumeImgStyle()
  12. Text('新建文件')
  13. .consumeTextStyle(Color.White, 20, 500)
  14. }
  15. }
  16. .consumeButtonStyle(Color.Green)
  17. .onClick(() => {
  18. console.log('我准备开始建立文件夹');
  19. })
  20. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  21. Row({ space: 10 }) {
  22. Image($r('app.media.icon_new_folder'))
  23. .consumeImgStyle()
  24. Text('新建文件')
  25. .consumeTextStyle(Color.White, 20, 500)
  26. }
  27. }
  28. .consumeButtonStyle(Color.Green)
  29. .onClick(() => {
  30. console.log('我准备开始建立文件夹');
  31. })
  32. }
  33. .width('100%')
  34. .height("100%")
  35. .justifyContent(FlexAlign.Center)
  36. }
  37. }
  38. @Extend(Image) function consumeImgStyle() {
  39. .width(30)
  40. .height(30)
  41. }
  42. @Extend(Button) function consumeButtonStyle(color: Color) {
  43. .fontSize(25)
  44. .width(150)
  45. .height(65)
  46. .backgroundColor(color)
  47. }
  48. @Extend(Text) function consumeTextStyle(color: Color, size: number, weight: number) {
  49. .fontSize(size)
  50. .fontColor(color)
  51. .fontWeight(weight)
  52. }

UI结构复用


       当页面有多个相同的UI结构时,若每个都单独声明,同样会有大量重复的代码。为避免重复代码,可以将相同的UI结构提炼为一个自定义组件,完成UI结构的复用。
       除此之外,ArkTS还提供了一种更轻量的UI结构复用机制@Builder方法,开发者可以将重复使用的UI元素抽象成一个@Builder方法,该方法可在build()方法中调用多次,以完成UI结构的复用。 

     @Builder装饰的方法同样可用于组件接结构的复用,

  • @Builder方法可以定义在组件内或者全局
  • @Builder方法定义的是组件内的@Builder方法,可通过this访问当前组件的属性和方法,而全局的@Builder方法则不能
  • @Builder方法定义的是组件内的@Builder方法只能用于当前组件,全局的@Builder方法导出(export)后,可用于整个应用。
  1. @Entry
  2. @Component
  3. struct BuilderUI {
  4. @State isOn: boolean = false;
  5. @State isDel: boolean = false;
  6. build() {
  7. Column({ space: 10 }) {
  8. this.builderButton($r('app.media.icon_delete'), '删除文件', () => {
  9. console.log('我准备开始删除文件夹');
  10. })
  11. globalBuilderButton($r('app.media.icon_new_folder'), '新建文件', () => {
  12. console.log('我准备开始建立文件夹');
  13. })
  14. }
  15. .width('100%')
  16. .height("100%")
  17. .justifyContent(FlexAlign.Center)
  18. }
  19. @Builder builderButton(icon: Resource, text: string, callback: () => void) {
  20. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  21. Row({ space: 10 }) {
  22. Image(icon)
  23. .width(30)
  24. .height(30)
  25. Text(text)
  26. .fontSize(20)
  27. .fontColor(Color.White)
  28. .fontWeight(500)
  29. .backgroundColor(Color.Green)
  30. }
  31. }
  32. .fontSize(25)
  33. .width(150)
  34. .height(65)
  35. .onClick(callback)
  36. }
  37. }
  38. @Builder function globalBuilderButton(icon: Resource, text: string, callback: () => void) {
  39. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  40. Row({ space: 10 }) {
  41. Image(icon)
  42. .width(30)
  43. .height(30)
  44. Text(text)
  45. .fontSize(20)
  46. .fontColor(Color.White)
  47. .fontWeight(500)
  48. .backgroundColor(Color.Green)
  49. }
  50. }
  51. .fontSize(25)
  52. .width(150)
  53. .height(65)
  54. .onClick(callback)
  55. }
  • @Builder方法支持参数传递规则,分为按值传递和按引用传递。带有花括号的{ } 为引用传递,其余为值传递。
  • 按引用传递时,若传递的参数为状态变量,则状态变量的变化将会触发@Builder方法内部UI的刷新,而按值传递时则不会。
  1. @Entry
  2. @Component
  3. struct BuilderUI {
  4. @State status: number = 10;
  5. build() {
  6. Column({ space: 10 }) {
  7. valueText(this.status)
  8. referenceText({status:this.status})
  9. Row({ space: 10 }) {
  10. Button('值传递 - 1')
  11. .consumeButtonStyle()
  12. .onClick(() => {
  13. this.status--
  14. })
  15. Button('引用传递 + 1')
  16. .consumeButtonStyle()
  17. .onClick(() => {
  18. this.status++
  19. })
  20. }
  21. }
  22. .width('100%')
  23. .height("100%")
  24. .justifyContent(FlexAlign.Center)
  25. }
  26. }
  27. @Builder function valueText(count: number) {
  28. Text(`进行值传递: ${count}`).fontSize(30).fontWeight(600)
  29. }
  30. @Builder function referenceText(count: {status:number}) {
  31. Text(`进行引用传递: ${count.status}`).fontSize(30).fontWeight(600)
  32. Text('引用参数传递的是状态变量status,这里内部UI会刷新')
  33. }
  34. @Extend(Button) function consumeButtonStyle() {
  35. .fontSize(20)
  36. .width(140)
  37. .height(65)
  38. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/714587
推荐阅读
相关标签
  

闽ICP备14008679号