ArkUI 布局优化:嵌套少一层,页面顺一截

举报
蓝瘦的蜕变 发表于 2026/08/13 11:42:15 2026/08/13
【摘要】 今天我们不做性能压测,只把几种常见布局写法摆在一起看:什么时候该少套一层,什么时候该抽一个 Builder。 初学 ArkUI 时,很容易一看到对齐问题就继续套 Row、Column。这样能写出来,但代码读起来会越来越绕。我们先看一个过度嵌套的小块,再看一个更扁平的写法。 第一块故意写得偏绕。只是标题、描述和一点说明,

ArkUI 布局优化:嵌套少一层,页面顺一截

今天我们不做性能压测,只把几种常见布局写法摆在一起看:什么时候该少套一层,什么时候该抽一个 Builder。

初学 ArkUI 时,很容易一看到对齐问题就继续套 Row、Column。这样能写出来,但代码读起来会越来越绕。我们先看一个过度嵌套的小块,再看一个更扁平的写法。

第一块故意写得偏绕。只是标题、描述和一点说明,却套了好几层。它不是不能用,而是维护时不够直观。

第二块把内容压回一层 Row。左侧 Column 用 layoutWeight(1) 占剩余空间,右侧放按钮。这个结构更像我们真正想表达的 UI:一段主要信息,加一个操作区。

第三块展示 Builder。重复出现的小行、信息块、标签组,都可以抽成 Builder。这样主体页面会更短,读代码时也更容易找到重点。

你现在项目里有没有那种“明明只是一个小卡片,却套了六七层”的布局?这种代码通常不是谁故意写复杂,而是一路修出来的。

完整代码

class OptimizationPoint {
  title: string
  desc: string
  color: string

  constructor(title: string, desc: string, color: string) {
    this.title = title
    this.desc = desc
    this.color = color
  }
}

@Entry
@Component
struct ArkUILayoutOptimizationDemo {
  private points: OptimizationPoint[] = [
    new OptimizationPoint('少套容器', '只是为了留白或对齐时,先看看现有组件属性够不够。', '#2563EB'),
    new OptimizationPoint('扁平分组', '同一层级的内容尽量放在同一个布局里,阅读代码更快。', '#0F766E'),
    new OptimizationPoint('抽出 Builder', '重复小块可以抽成 Builder,结构会更稳。', '#C2410C')
  ]

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 6 }) {
      Text(title)
        .fontSize(19)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text(desc)
        .fontSize(13)
        .fontColor('#6B7280')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  nestedCard() {
    Column({ space: 8 }) {
      Row() {
        Column() {
          Row() {
            Column({ space: 4 }) {
              Text('过度嵌套')
                .fontSize(17)
                .fontWeight(FontWeight.Bold)
                .fontColor('#B91C1C')
              Text('Column > Row > Column > Row')
                .fontSize(12)
                .fontColor('#6B7280')
            }
            .padding(10)
            .backgroundColor('#FEF2F2')
            .borderRadius(8)
          }
          .width('100%')
        }
        .width('100%')
      }
      .width('100%')

      Text('如果只是为了标题、描述、按钮排在一起,这么套会让后续维护很累。')
        .fontSize(13)
        .fontColor('#4B5563')
        .lineHeight(20)
    }
    .width('100%')
    .padding(14)
    .borderRadius(12)
    .backgroundColor('#FFF7ED')
    .border({ width: 1, color: '#FED7AA' })
  }

  @Builder
  flatCard() {
    Row({ space: 12 }) {
      Column({ space: 6 }) {
        Text('更扁平')
          .fontSize(17)
          .fontWeight(FontWeight.Bold)
          .fontColor('#047857')
        Text('Row + layoutWeight 就能把主内容和操作区分开。')
          .fontSize(13)
          .fontColor('#4B5563')
          .lineHeight(20)
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)

      Text('查看')
        .fontSize(13)
        .fontWeight(FontWeight.Medium)
        .fontColor('#FFFFFF')
        .height(36)
        .padding({ left: 16, right: 16 })
        .borderRadius(18)
        .backgroundColor('#0F766E')
    }
    .width('100%')
    .padding(14)
    .borderRadius(12)
    .backgroundColor('#ECFDF5')
    .border({ width: 1, color: '#A7F3D0' })
  }

  @Builder
  pointRow(item: OptimizationPoint) {
    Row({ space: 12 }) {
      Text(item.title.substring(0, 1))
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .textAlign(TextAlign.Center)
        .width(38)
        .height(38)
        .borderRadius(19)
        .backgroundColor(item.color)

      Column({ space: 4 }) {
        Text(item.title)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor('#111827')
        Text(item.desc)
          .fontSize(13)
          .fontColor('#4B5563')
          .lineHeight(20)
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .padding(12)
    .borderRadius(10)
    .backgroundColor('#F8FAFC')
    .border({ width: 1, color: '#E5E7EB' })
  }

  build() {
    Scroll() {
      Column({ space: 22 }) {
        Column({ space: 8 }) {
          Text('ArkUI 布局优化')
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text('嵌套少一层,页面顺一截')
            .fontSize(16)
            .fontColor('#4B5563')
          Text('这一篇不做性能压测,只把常见的布局写法放在一起看:什么时候该少套一层,什么时候该抽成小块。')
            .fontSize(14)
            .fontColor('#6B7280')
            .lineHeight(22)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('对比一:只是排列内容,别套太深', '嵌套不是错,但每多一层都应该有明确理由。')
        this.nestedCard()
        this.flatCard()

        this.sectionTitle('对比二:重复结构交给 Builder', '列表里的小行、信息块、标签组,抽出来之后主体会清爽很多。')
        Column({ space: 10 }) {
          ForEach(this.points, (item: OptimizationPoint) => {
            this.pointRow(item)
          }, (item: OptimizationPoint) => item.title)
        }
        .width('100%')

        this.sectionTitle('对比三:优先用组件自己的布局属性', '比如 space、padding、layoutWeight、alignItems,很多时候已经能解决排列问题。')
        Column({ space: 10 }) {
          Row({ space: 8 }) {
            Text('space')
              .fontSize(13)
              .fontColor('#1D4ED8')
              .padding({ left: 12, right: 12, top: 8, bottom: 8 })
              .borderRadius(16)
              .backgroundColor('#DBEAFE')
            Text('padding')
              .fontSize(13)
              .fontColor('#0F766E')
              .padding({ left: 12, right: 12, top: 8, bottom: 8 })
              .borderRadius(16)
              .backgroundColor('#CCFBF1')
            Text('alignItems')
              .fontSize(13)
              .fontColor('#C2410C')
              .padding({ left: 12, right: 12, top: 8, bottom: 8 })
              .borderRadius(16)
              .backgroundColor('#FFEDD5')
          }
          .width('100%')

          Text('先把这些基础属性用顺,很多页面不会一开始就走向复杂嵌套。')
            .fontSize(13)
            .fontColor('#4B5563')
            .lineHeight(20)
            .width('100%')
            .padding(12)
            .borderRadius(10)
            .backgroundColor('#F9FAFB')
        }
        .width('100%')
      }
      .width('100%')
      .padding({ left: 18, right: 18, top: 22, bottom: 32 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。