鸿蒙开发入门指南:前端开发者快速掌握常用布局
-
- 布局的核心思想:从盒模型到组件树
- 布局元素的组成:鸿蒙版的盒模型
- 布局选择指南:Flexbox还是Grid?
- 栅格布局(GridRow/GridCol):响应式设计的终极武器
- 弹性布局(Flex):增强版的线性布局
-
- [从CSS Flexbox到鸿蒙Flex](#从CSS Flexbox到鸿蒙Flex)
- 基本用法示例
- 自适应拉伸的深入理解
- 线性布局(Row/Column):最基础的布局
- 布局位置:绝对定位与相对定位
- 对子元素的约束:自适应布局的进阶技巧
-
- [1. 拉伸(flexGrow/flexShrink)](#1. 拉伸(flexGrow/flexShrink))
- [2. 缩放(aspectRatio)](#2. 缩放(aspectRatio))
- [3. 占比(百分比和layoutWeight)](#3. 占比(百分比和layoutWeight))
- [4. 隐藏(displayPriority)](#4. 隐藏(displayPriority))
- 实战技巧:从简单到复杂
- [从Element Plus布局理解ArkUI:前端开发者的思维桥梁](#从Element Plus布局理解ArkUI:前端开发者的思维桥梁)
-
- [1. Container布局容器 → 基础组件嵌套](#1. Container布局容器 → 基础组件嵌套)
- [2. Layout布局组件 → Row/Column线性布局](#2. Layout布局组件 → Row/Column线性布局)
- [3. 更强大的栅格系统:GridRow/GridCol](#3. 更强大的栅格系统:GridRow/GridCol)
- [4. 思维转换:从Element Plus到ArkUI](#4. 思维转换:从Element Plus到ArkUI)
- 性能优化建议
- 总结:布局选择策略
- 从Web前端到鸿蒙布局:完整概念对照表
- 最后的话
大家好,我是你们的老朋友木斯佳。说实话,刚开始接触ArkUI的声明式UI时,我的第一反应是:"这不就是Flexbox吗?"但随着学习的深入,我发现鸿蒙的布局系统不仅有Flexbox的影子,还有CSS Grid的强大能力,甚至超越了两者的结合。
今天,我就以一个前端开发者的视角,带大家深入探索HarmonyOS的布局系统。我们会一起看看这些布局概念如何与我们熟悉的前端知识对应,又有哪些独特的亮点。
布局的核心思想:从盒模型到组件树

在HarmonyOS的声明式UI中,页面由自定义组件构成。这就像我们前端的DOM树,开发者需要像搭积木一样,按照一定的布局规则来组织这些组件。
布局的本质是什么?其实就是管理UI组件的大小和位置。开发一个页面时,我们可以遵循这样的流程:
- 确定页面的布局结构 - 先想好整体框架(类似前端的页面架构设计)
- 分析页面中的元素构成 - 拆解页面有哪些组件(类似前端的组件化思维)
- 选用适合的布局容器 - 选择合适的布局方式(类似选择Flexbox还是Grid)
一个典型的页面结构通常是分层的,就像我们熟悉的HTML嵌套结构:
Page (根节点)
├── Column (垂直布局)
│ ├── Row (水平布局)
│ ├── Row (水平布局)
│ └── ...
└── ...
布局元素的组成:鸿蒙版的盒模型

在深入具体布局之前,我们需要理解布局元素的几个关键区域。如果你熟悉CSS的盒模型,这部分会非常容易理解:
- 组件区域 :组件的大小,由
width、height属性控制(类似CSS的content + padding + border) - 组件内容区:组件区域减去边框(border)后的区域(类似CSS的content + padding)
- 组件内容:实际内容占用的区域,比如文本(类似CSS的content)
- 组件布局边界:组件区域加上外边距(margin)(类似CSS的margin box)
前端视角 :这完全就是我们熟悉的盒模型!只是名称略有不同。在CSS中,我们经常纠结于box-sizing: border-box,而在鸿蒙中,组件的宽度高度默认就包含padding和border,更符合直觉。
布局选择指南:Flexbox还是Grid?
HarmonyOS提供了多种布局方式,我整理了一个与前端概念的对照表:
| 鸿蒙布局 | 适用场景 | 类似前端概念 |
|---|---|---|
| 线性布局(Row/Column) | 子元素线性排列 | Flexbox的flex-direction |
| 层叠布局(Stack) | 需要堆叠效果 | position: absolute/relative |
| 弹性布局(Flex) | 需要拉伸或压缩子元素 | Flexbox |
| 相对布局(RelativeContainer) | 复杂二维布局,避免嵌套过深 | CSS Grid的部分功能 |
| 栅格布局(GridRow/GridCol) | 多设备适配、复杂页面结构 | CSS Grid + 媒体查询 |
| 选项卡(Tabs) | 内容切换 | Tab组件 |
重点来了!栅格布局是鸿蒙布局系统中一个非常强大的特性,它结合了CSS Grid的灵活性和媒体查询的响应式能力。下面我会重点介绍这个布局。
栅格布局(GridRow/GridCol):响应式设计的终极武器

如果你做过响应式网页设计,一定用过Bootstrap的栅格系统或CSS Grid。鸿蒙的栅格布局就是类似的概念,但它更强大------原生支持断点设置,完美适配不同尺寸的设备。
核心优势
- 提供可循的规律:为布局提供规律性的结构,解决多尺寸多设备的动态布局问题
- 统一的定位标注:保证不同设备上各个模块的布局一致性
- 灵活的间距调整:通过调整列间距和行间距,控制排版效果
- 自动换行和自适应:元素数量超出一行时自动换行,在不同设备上自适应排版
前端视角:这就像CSS Grid搭配媒体查询,但鸿蒙将其封装成了声明式组件,使用起来更加直观。
断点系统:鸿蒙版的媒体查询
栅格容器以设备的水平宽度作为断点依据,默认将设备宽度分为四类:
| 断点 | 取值范围(vp) | 设备描述 |
|---|---|---|
| xs | [0, 320) | 最小宽度类型设备(类似手机竖屏) |
| sm | [320, 600) | 小宽度类型设备(类似手机横屏) |
| md | [600, 840) | 中等宽度类型设备(类似平板竖屏) |
| lg | [840, +∞) | 大宽度类型设备(类似平板横屏) |
更强大的是,我们可以自定义断点,最多支持6个断点(xs, sm, md, lg, xl, xxl):
typescript
GridRow({
breakpoints: {
value: ['320vp', '600vp', '840vp', '1440vp', '1600vp'],
reference: BreakpointsReference.WindowSize // 以窗口宽度为参照
}
}) {
// 子组件
}
前端视角:这就像在CSS中定义媒体查询:
css
/* 相当于鸿蒙的断点设置 */
@media (min-width: 0) and (max-width: 319px) { /* xs */ }
@media (min-width: 320px) and (max-width: 599px) { /* sm */ }
@media (min-width: 600px) and (max-width: 839px) { /* md */ }
@media (min-width: 840px) { /* lg */ }
但鸿蒙的断点系统更加灵活,可以动态监听断点变化:
typescript
GridRow()
.onBreakpointChange((breakPoint) => {
console.log('当前断点:', breakPoint);
})
设置栅格列数
通过columns设置栅格布局的总列数:
typescript
// 方式1:固定列数(所有设备都是8列)
GridRow({ columns: 8 }) { ... }
// 方式2:响应式列数(不同断点不同列数)
GridRow({
columns: {
xs: 2, // 手机竖屏:2列
sm: 4, // 手机横屏:4列
md: 8, // 平板竖屏:8列
lg: 12 // 平板横屏:12列
}
}) { ... }
前端视角:对比CSS Grid:
css
/* 鸿蒙的响应式列数设置相当于 */
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr); /* xs */
}
@media (min-width: 320px) {
.grid {
grid-template-columns: repeat(4, 1fr); /* sm */
}
}
@media (min-width: 600px) {
.grid {
grid-template-columns: repeat(8, 1fr); /* md */
}
}
鸿蒙的方式显然更加简洁,不需要写多个媒体查询。
排列方向和间距
typescript
// 排列方向(从左往右或从右往左)
GridRow({ direction: GridRowDirection.RowReverse }) { ... }
// 设置间距
GridRow({
gutter: { x: 20, y: 50 } // 水平间距20,垂直间距50
}) { ... }
栅格子组件(GridCol)
GridCol作为GridRow的子组件,通过span(占用列数)、offset(偏移列数)、order(元素序号)来控制布局。
span:占用列数
typescript
// 方式1:固定占用列数
GridCol({ span: 2 }) {
Text('占2列')
}
// 方式2:响应式占用列数
GridCol({
span: {
xs: 1, // 手机竖屏占1列
sm: 2, // 手机横屏占2列
md: 3, // 平板竖屏占3列
lg: 4 // 平板横屏占4列
}
}) {
Text('响应式宽度')
}
前端视角:相当于CSS Grid中的:
css
/* 鸿蒙的span:2 相当于 */
.grid-col {
grid-column: span 2;
}
/* 响应式span相当于 */
.grid-col {
grid-column: span 1; /* xs */
}
@media (min-width: 320px) {
.grid-col {
grid-column: span 2; /* sm */
}
}
offset:偏移列数
typescript
// 固定偏移
GridCol({ offset: 2, span: 1 }) {
Text('向右偏移2列')
}
// 响应式偏移
GridCol({
offset: {
xs: 0,
sm: 1,
md: 2,
lg: 3
},
span: 1
}) {
Text('响应式偏移')
}
前端视角 :相当于CSS Grid的grid-column-start,但更简洁。
order:重新排序
typescript
// 固定排序
GridCol({ order: 3, span: 1 }) { Text('第三个显示') }
GridCol({ order: 1, span: 1 }) { Text('第一个显示') }
GridCol({ order: 2, span: 1 }) { Text('第二个显示') }
// 响应式排序
GridCol({
order: {
xs: 1, // 手机竖屏时排第1
sm: 3, // 手机横屏时排第3
md: 2, // 平板竖屏时排第2
lg: 4 // 平板横屏时排第4
},
span: 1
}) {
Text('响应式顺序')
}
前端视角 :相当于CSS的order属性,但可以响应式变化,这在纯CSS中实现起来比较麻烦。
栅格嵌套:构建复杂布局
栅格组件可以嵌套使用,就像CSS Grid中可以嵌套Grid一样:
typescript
@Entry
@Component
struct GridNestingExample {
build() {
GridRow({ columns: 12 }) {
// 顶部区域
GridCol({ span: 12 }) {
GridRow({ columns: 12 }) {
GridCol({ span: 2 }) {
Text('左侧菜单')
}
GridCol({ span: 10 }) {
Text('内容区域')
}
}
}
// 底部区域
GridCol({ span: 12 }) {
Text('页脚')
}
}
}
}
这个例子中:
- 外层GridRow将整个页面分为12列
- 第一个GridCol占满12列,内部又嵌套了一个GridRow,将顶部区域分为左侧菜单(2列)和内容区域(10列)
- 第二个GridCol占满12列,作为页脚
前端视角:这种嵌套方式让我们可以像搭积木一样构建复杂的页面结构,每一层都是独立的栅格系统,互不影响。
弹性布局(Flex):增强版的线性布局

说完了栅格布局,我们再回顾一下弹性布局,它是线性布局的增强版。
从CSS Flexbox到鸿蒙Flex
如果你熟悉CSS Flexbox,学习鸿蒙的Flex布局会非常轻松。下面是完整的对照表:
| CSS Flexbox | 鸿蒙Flex | 说明 |
|---|---|---|
| display: flex | Flex() | 弹性容器 |
| flex-direction | direction | 主轴方向 |
| justify-content | justifyContent | 主轴对齐方式 |
| align-items | alignItems | 交叉轴对齐方式 |
| align-self | alignSelf | 单个元素交叉轴对齐 |
| flex-wrap | wrap | 是否换行 |
| flex-grow | flexGrow | 拉伸比例 |
| flex-shrink | flexShrink | 压缩比例 |
| flex-basis | flexBasis | 基准尺寸 |
| order | (通过alignSelf?) | 排序(目前鸿蒙Flex没有直接的order属性) |
基本用法示例
typescript
Flex({
direction: FlexDirection.Row, // 主轴方向(默认水平)
wrap: FlexWrap.Wrap, // 允许换行
justifyContent: FlexAlign.SpaceBetween, // 主轴两端对齐
alignItems: ItemAlign.Center // 交叉轴居中对齐
}) {
Text('项目1').width(100).height(50)
Text('项目2').width(100).height(50)
Text('项目3').width(100).height(50)
}
自适应拉伸的深入理解
弹性布局最强大的地方在于自适应能力,我们深入理解一下:
typescript
// flexGrow:按比例分配剩余空间
Flex() {
Text('项目1').flexGrow(1).width(100) // 占剩余空间的1份
Text('项目2').flexGrow(2).width(100) // 占剩余空间的2份
Text('项目3').width(100) // 不拉伸
}
// 假设父容器宽度500,三个子元素原始宽度300,剩余200
// 项目1增加:200 × (1/3) ≈ 67
// 项目2增加:200 × (2/3) ≈ 133
// 最终:项目1:167,项目2:233,项目3:100
// flexShrink:空间不足时的压缩比例
Flex() {
Text('项目1').flexShrink(3).width(200) // 压缩比例大
Text('项目2').width(200) // 默认压缩比例1
Text('项目3').flexShrink(2).width(200) // 压缩比例中等
}
// 假设父容器宽度400,三个子元素原始宽度600,超出200
// 项目1压缩:200 × (3/6) = 100
// 项目2压缩:200 × (1/6) ≈ 33
// 项目3压缩:200 × (2/6) ≈ 67
// 最终:项目1:100,项目2:167,项目3:133
前端视角:和CSS Flexbox的计算方式完全一致!
线性布局(Row/Column):最基础的布局

线性布局是最基础、最常用的布局方式,通过Row(水平)和Column(垂直)实现。
基础用法
typescript
// 垂直布局,子元素间距20
Column({ space: 20 }) {
Text('项目1')
Text('项目2')
Text('项目3')
}
// 水平布局,子元素间距35
Row({ space: 35 }) {
Text('项目1')
Text('项目2')
Text('项目3')
}
主轴对齐方式
typescript
// 垂直居中对齐
Column() {
// ...子元素
}.justifyContent(FlexAlign.Center)
// 两端对齐
Row() {
// ...子元素
}.justifyContent(FlexAlign.SpaceBetween)
可用的对齐方式与Flex布局完全相同。
交叉轴对齐方式
typescript
// Column的交叉轴是水平方向
Column() {
// ...子元素
}.alignItems(HorizontalAlign.Center) // 水平居中
// Row的交叉轴是垂直方向
Row() {
// ...子元素
}.alignItems(VerticalAlign.Center) // 垂直居中
布局位置:绝对定位与相对定位
鸿蒙也支持类似CSS的定位能力:
typescript
// 绝对定位(类似position: absolute)
Text('绝对定位')
.position({ x: 100, y: 200 }) // 相对于父容器左上角偏移
// 相对定位(类似position: relative)
Text('相对定位')
.offset({ x: 20, y: 30 }) // 相对于自身原位置偏移,原位置保留
对子元素的约束:自适应布局的进阶技巧
1. 拉伸(flexGrow/flexShrink)
已在Flex布局中详细介绍
2. 缩放(aspectRatio)
typescript
// 设置宽高比,宽度变化时高度按比例变化
Image('example.jpg')
.width(200)
.aspectRatio(1.5) // width:height = 1.5:1,高度 = 200/1.5 ≈ 133
3. 占比(百分比和layoutWeight)
typescript
// 百分比宽度
Row() {
Column().width('20%') // 占父容器宽度的20%
Column().width('50%') // 占50%
Column().width('30%') // 占30%
}
// layoutWeight:按权重分配剩余空间
Row() {
Column().layoutWeight(1) // 占1份
Column().layoutWeight(2) // 占2份
Column().layoutWeight(3) // 占3份
}
// 假设父容器宽度600,三个子元素都未设置宽度
// 总权重6,每份宽度100
// 三个子元素宽度分别为:100、200、300
4. 隐藏(displayPriority)
typescript
// 根据优先级显示/隐藏
Row() {
Text('重要内容').displayPriority(1) // 优先级高,优先显示
Text('次要内容').displayPriority(2) // 优先级中
Text('可选内容').displayPriority(3) // 优先级低,空间不足时最先隐藏
}
当容器空间不足时,优先级高的元素保留,优先级低的元素自动隐藏。
实战技巧:从简单到复杂
技巧1:使用Blank填充空白
typescript
// 类似flex:1的效果
Row() {
Text('左侧文字')
Blank() // 自动填充剩余空间
Button('确认')
}
.width('100%')
技巧2:栅格+弹性实现复杂响应式卡片
typescript
@Entry
@Component
struct ResponsiveCardGrid {
build() {
GridRow({
columns: { xs: 1, sm: 2, md: 3, lg: 4 },
gutter: { x: 16, y: 16 }
}) {
// 生成12个卡片
ForEach([...Array(12).keys()], (index) => {
GridCol({
span: { xs: 1, sm: 1, md: 1, lg: 1 }
}) {
Column() {
Image(`https://picsum.photos/200/150?random=${index}`)
.width('100%')
.aspectRatio(4/3)
Text(`卡片 ${index + 1}`)
.fontSize(16)
.margin({ top: 8 })
Text('这是一段描述文字')
.fontSize(14)
.fontColor('#666')
}
.padding(12)
.backgroundColor('#fff')
.borderRadius(8)
.shadow({ radius: 4, color: '#ccc' })
}
})
}
.padding(16)
}
}
这个例子中:
- 使用栅格实现响应式布局:手机1列,小平板2列,大平板3列,桌面4列
- 卡片内部使用Column进行垂直布局
- 图片设置aspectRatio保持比例
- 添加了阴影和圆角,让卡片更美观
技巧3:导航栏的多种实现对比
方式1:线性布局 + Blank
typescript
Row() {
Image('logo.png').width(40)
Text('应用名称').fontSize(18)
Blank()
Row({ space: 20 }) {
Text('首页')
Text('产品')
Text('关于')
}
}
.width('100%')
.padding({ left: 16, right: 16 })
方式2:弹性布局
typescript
Flex({
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
Row({ space: 8 }) {
Image('logo.png').width(40)
Text('应用名称').fontSize(18)
}
Row({ space: 20 }) {
Text('首页')
Text('产品')
Text('关于')
}
}
.width('100%')
.padding({ left: 16, right: 16 })
方式3:栅格布局
typescript
GridRow({ columns: 12, gutter: { x: 0 } }) {
GridCol({ span: 2 }) {
Row({ space: 8 }) {
Image('logo.png').width(40)
Text('应用名称').fontSize(18)
}
}
GridCol({ span: 8 }) {
// 留白区域
}
GridCol({ span: 2 }) {
Row({ space: 20, justifyContent: FlexAlign.End }) {
Text('首页')
Text('产品')
Text('关于')
}
}
}
.width('100%')
.padding({ left: 16, right: 16 })
三种方式都能实现类似效果,但各有优劣:
- 线性布局+Blank:最简单直观,适合简单场景
- 弹性布局:更灵活,适合需要精确控制对齐的场景
- 栅格布局:最规范,适合复杂页面和对齐要求严格的场景
从Element Plus布局理解ArkUI:前端开发者的思维桥梁
作为前端开发者,我们最熟悉的UI框架之一就是Element Plus。它的布局组件设计思想,可以帮助我们更好地理解ArkUI的布局系统。下面我用Element Plus的视角,重新解读一下ArkUI的布局设计。
1. Container布局容器 → 基础组件嵌套

Element Plus 提供了el-container、el-header、el-aside、el-main、el-footer这些语义化的布局容器:
vue
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
<el-footer>Footer</el-footer>
</el-container>
ArkUI的等价实现:
typescript
Column() { // 相当于最外层的el-container
Row() { // 相当于el-header
Text('Header')
}.height(60).width('100%')
Row() { // 相当于内层的el-container(水平方向)
Column() { // 相当于el-aside
Text('Aside')
}.width(200)
Column() { // 相当于el-main
Text('Main')
}.layoutWeight(1) // flex:1,自动填充剩余宽度
}.layoutWeight(1) // 自动填充剩余高度
.width('100%')
Row() { // 相当于el-footer
Text('Footer')
}.height(60).width('100%')
}
.height('100%')
.width('100%')
理解要点:
Column= 垂直方向的容器(相当于el-container的垂直布局)Row= 水平方向的容器(相当于el-container的水平布局)layoutWeight= 类似CSS的flex:1,自动撑满剩余空间
2. Layout布局组件 → Row/Column线性布局

Element Plus 的el-row和el-col是我们最常用的布局组件:
vue
<el-row :gutter="20">
<el-col :span="6"><div>占6列</div></el-col>
<el-col :span="6"><div>占6列</div></el-col>
<el-col :span="6"><div>占6列</div></el-col>
<el-col :span="6"><div>占6列</div></el-col>
</el-row>
<!-- 对齐方式 -->
<el-row justify="center">
<el-col :span="4">居中</el-col>
</el-row>
ArkUI的等价实现:
typescript
// Row相当于el-row,space相当于gutter
Row({ space: 20 }) {
// 每个子组件相当于el-col,但需要手动设置宽度
Text('占6列').width('25%') // 12列栅格中span=6相当于25%
Text('占6列').width('25%')
Text('占6列').width('25%')
Text('占6列').width('25%')
}
// 对齐方式
Row() {
Text('居中').width('20%')
Text('居中').width('20%')
}
.justifyContent(FlexAlign.Center) // 相当于justify="center"
概念对照:
| Element Plus | ArkUI | 说明 |
|---|---|---|
| el-row | Row/Column | 布局容器 |
| :gutter | space | 子元素间距 |
| justify | justifyContent | 主轴对齐方式 |
| align | alignItems | 交叉轴对齐方式 |
| :span | width百分比或GridCol的span | 占用宽度 |
3. 更强大的栅格系统:GridRow/GridCol
Element Plus的栅格系统已经很好用了,但ArkUI的GridRow/GridCol更加强大,它内置了响应式断点系统:
Element Plus的响应式栅格:
vue
<el-row :gutter="10">
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">
<div>响应式列</div>
</el-col>
</el-row>
ArkUI的响应式栅格:
typescript
GridRow({
columns: { xs: 2, sm: 4, md: 8, lg: 12 }, // 不同断点的总列数
gutter: { x: 10, y: 10 }
}) {
GridCol({
span: { xs: 1, sm: 1, md: 1, lg: 1 } // 不同断点占用的列数
}) {
Text('响应式列')
}
}
为什么ArkUI的栅格更强大?
- 断点可自定义:可以自由设置断点阈值
- 可监听断点变化 :通过
onBreakpointChange动态响应 - 更细粒度的控制 :支持
offset偏移和order排序的响应式配置
typescript
// ArkUI的高级特性:监听断点变化
GridRow()
.onBreakpointChange((breakPoint) => {
if (breakPoint === 'xs') {
// 手机竖屏时特殊处理
this.showCompactMode = true
}
})
4. 思维转换:从Element Plus到ArkUI
如果你熟悉Element Plus,可以用这个思维模型来学习ArkUI:
| Element Plus的使用经验 | ArkUI的对应概念 |
|---|---|
页面骨架用el-container |
用Column/Row嵌套,配合layoutWeight |
内容区域用el-row/el-col |
用Row/Column设置space和百分比宽度 |
复杂响应式用el-col的:xs/:sm/:md |
用GridRow/GridCol的断点系统 |
Flex布局用justify/align |
用justifyContent/alignItems |
间距用gutter |
用space(线性布局)或gutter(栅格布局) |
一句话总结:如果你会用Element Plus的Layout布局组件,那么你已经掌握了ArkUI布局的80%!剩下的20%是ArkUI独有的强大特性(如断点监听、优先级隐藏等),这些反而是锦上添花的加分项。
性能优化建议
在复杂界面中使用多组件嵌套时,需要注意性能问题:
- 减少嵌套层级:过深的嵌套会产生额外开销
- 合理选择布局:能用线性布局解决的问题,就不要用弹性布局;能用弹性布局解决的问题,就不要用栅格布局
- 使用渲染控制 :合理使用
ForEach、if等控制组件渲染 - 避免不必要的重新渲染 :使用
@State、@Prop等装饰器时注意状态变化的影响
总结:布局选择策略
根据我的实践经验,总结一个布局选择策略:
| 场景 | 推荐布局 | 理由 |
|---|---|---|
| 简单的线性排列 | Row/Column | 最简单,性能最好 |
| 需要拉伸/压缩 | Flex | 提供了flexGrow/flexShrink |
| 需要堆叠效果 | Stack | 类似position: absolute |
| 复杂响应式布局 | GridRow/GridCol | 断点系统最强大 |
| 避免嵌套过深 | RelativeContainer | 二维定位,减少嵌套 |
| 多设备适配 | GridRow/GridCol + 断点 | 一次编写,多端适配 |
从Web前端到鸿蒙布局:完整概念对照表
最后,送上一份完整的概念对照表:
| Web前端 | HarmonyOS | 说明 |
|---|---|---|
| display: flex | Flex | 弹性布局容器 |
| display: grid | GridRow/GridCol | 栅格布局容器 |
| flex-direction | direction | 主轴方向 |
| justify-content | justifyContent | 主轴对齐方式 |
| align-items | alignItems | 交叉轴对齐方式 |
| align-self | alignSelf | 单个元素交叉轴对齐 |
| flex-wrap | wrap | 是否换行 |
| flex-grow | flexGrow | 拉伸比例 |
| flex-shrink | flexShrink | 压缩比例 |
| flex-basis | flexBasis | 基准尺寸 |
| grid-template-columns | columns | 栅格列数定义 |
| grid-column | span | 占用列数 |
| margin-left/left | offset | 偏移列数 |
| order | order | 排序 |
| column-gap/row-gap | gutter | 栅格间距 |
| @media | breakpoints | 断点系统 |
| aspect-ratio | aspectRatio | 宽高比 |
| flex: 1 | layoutWeight | 权重分配 |
| display: none (条件) | displayPriority | 优先级隐藏 |
| margin | margin | 外边距 |
| padding | padding | 内边距 |
| width/height | width/height | 宽高 |
| position: absolute | position | 绝对定位 |
| position: relative | offset | 相对定位 |
最后的话
从Web前端转到HarmonyOS开发,你会发现很多概念都是相通的。特别是如果你熟悉Element Plus的布局组件,那么学习ArkUI布局会事半功倍。鸿蒙的布局系统吸收了CSS Flexbox和Grid的优点,又结合移动设备的特性进行了优化,特别是栅格布局的断点系统,让响应式设计变得异常简单。
希望通过这篇文章,能帮助你快速上手HarmonyOS的布局系统。如果你有任何问题或心得,欢迎在评论区留言交流!