HarmonyOS7 弹性布局实战:Flex 组件让我告别了嵌套地狱
为什么用 Flex
上次重构一个设置页面,我写了六层嵌套——Row套Column,Column再套Row,改一个间距要翻半天代码。同事看了一眼说:“你这代码是俄罗斯套娃吧?”
说实话,那一刻我意识到:不会用 Flex,写布局就是在折磨自己。
HarmonyOS7 的 Flex 弹性布局组件,真的是我用过最爽的布局方案之一。今天就来聊聊怎么用它告别嵌套地狱。
传统布局的痛点太明显了:
- Row/Column 只有一个方向,遇到既需要水平又需要垂直的场景就得套娃
- 对齐靠 margin 硬凑,改一处动全身
- 自适应差,不同屏幕尺寸得写多套布局
Flex 组件把方向、对齐、分布、换行这些能力打包在一起,一个组件顶三个 Row/Column 嵌套。
打个比方:Row/Column 就像只有直道的公路,Flex 是有立交桥的高速——想去哪,直接走,不用绕来绕去。

基础概念速览
先看看 Flex 跟 Row、Column 到底啥区别:
| 特性 | Row | Column | Flex |
|---|---|---|---|
| 主轴方向 | 水平 | 垂直 | 自由指定 |
| 子组件对齐 | 单一方向 | 单一方向 | 主轴+交叉轴 |
| 换行支持 | 无 | 无 | 支持 FlexWrap |
| 比例分配 | 无 | 无 | 支持 flexGrow |
| 嵌套需求 | 复杂布局需多层 | 复杂布局需多层 | 一层搞定 |
划重点:Flex 最大的优势是方向自由+换行+比例分配,这三个能力组合起来,能覆盖 90% 的布局场景。
实战案例一:等分布局
最常见的场景——几个按钮等分一行空间。

@Entry
@Component
struct EqualLayout {
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
ForEach(['首页', '发现', '消息', '我的'], (item: string) => {
Text(item)
.width('25%')
.height(48)
.textAlign(TextAlign.Center)
.backgroundColor('#f1f1f1')
.borderRadius(8)
})
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
}
}
关键代码讲解:
direction: FlexDirection.Row—— 指定主轴方向为水平,子组件从左到右排列alignItems: ItemAlign.Center—— 交叉轴(这里是垂直方向)居中对齐.width('25%')—— 每个子组件占 25%,四个刚好等分
用 Row 也能做等分,但 Flex 的好处是——后续要加对齐、间距,不用改结构,加个属性就行。
实战案例二:比例布局
不是所有场景都等分,比如侧边栏占 1 份,内容区占 3 份。这时候 flexGrow 就派上用场了。
@Entry
@Component
struct RatioLayout {
build() {
Flex({ direction: FlexDirection.Row }) {
Text('侧边栏')
.flexGrow(1)
.height('100%')
.backgroundColor('#e8e8e8')
.textAlign(TextAlign.Center)
Text('内容区')
.flexGrow(3)
.height('100%')
.backgroundColor('#ffffff')
.textAlign(TextAlign.Center)
}
.width('100%')
.height(400)
}
}

关键代码讲解:
.flexGrow(1)—— 侧边栏占 1 份剩余空间.flexGrow(3)—— 内容区占 3 份剩余空间- 两者比例 1:3,不管屏幕多宽,比例永远一致
说白了,flexGrow 就是按比例瓜分剩余空间的"分蛋糕"机制。谁设的数字大,谁分得多。如果某个组件不设 flexGrow,它就只占自身内容大小,不参与分蛋糕。
实战案例三:换行布局
标签列表、商品筛选这类场景——标签数量不确定,一行放不下要自动换行。这是 Row 做不到的。
@Entry
@Component
struct WrapLayout {
@State tags: string[] = [
'ArkTS', 'ArkUI', 'Flex', '布局', '组件',
'状态管理', '导航', '动画', '手势', '网络请求'
]
build() {
Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
ForEach(this.tags, (tag: string) => {
Text(tag)
.height(36)
.fontSize(14)
.padding({ left: 16, right: 16 })
.margin({ right: 8, bottom: 8 })
.backgroundColor('#f0f0f0')
.borderRadius(18)
})
}
.width('100%')
.padding(16)
}
}
关键代码讲解:
wrap: FlexWrap.Wrap—— 开启换行,子组件超出宽度自动换到下一行.margin({ right: 8, bottom: 8 })—— 标签间距用 margin 控制,简单直接FlexWrap.NoWrap(默认)不换行,子组件会被压缩或溢出
这个换行能力是 Flex 的杀手级功能。 之前用 Row 做标签列表,要么写死每行几个,要么自己算换行逻辑——现在一个属性搞定。
踩坑记录
用 Flex 踩过的几个坑,分享出来帮你避雷:
-
flexGrow 和 width 同时设会冲突
设了
flexGrow就别再设固定width,否则 flexGrow 会被忽略。这是最容易犯的错。 -
alignItems 和子组件 alignSelf 别搞混
alignItems是 Flex 容器级别的对齐,所有子组件统一生效;alignSelf是子组件级别的,可以覆盖容器的 alignItems。需要某个子组件特殊对齐时用 alignSelf。 -
FlexDirection.Reverse 的坑
FlexDirection.RowReverse会让子组件从右到左排列,但 ForEach 的顺序不变,视觉顺序和逻辑顺序相反,处理点击事件时要小心。 -
嵌套 Flex 性能没问题
两层 Flex 嵌套是完全 OK 的,别为了"避免嵌套"硬把所有逻辑塞一层。合理嵌套 > 强行平铺。
写在最后
Flex 组件本质上就是 HarmonyOS7 版的 CSS Flexbox,概念完全一致。如果你有 Web 开发经验,上手基本零成本。没有也没关系,记住这三个核心:
- direction —— 子组件往哪个方向排
- justifyContent —— 主轴怎么分布
- alignItems —— 交叉轴怎么对齐
掌握这三个,日常布局够用了。遇到换行和比例分配的场景,Flex 就是最佳选择。
别再写 Row 套 Column 的俄罗斯套娃了,试试 Flex,你会回来谢我的。
更多推荐


所有评论(0)