《uni-app跨平台开发完全指南》- 04 - 页面布局与样式基础
uni-app:掌握页面布局与样式
新手刚接触uni-app布局可能会遇到以下困惑:明明在模拟器上完美显示的页面,到了真机上就面目全非;iOS上对齐的元素,到Android上就错位几个像素,相信很多开发者都经历过。今天就带大家摸清了uni-app布局样式的门道,把这些经验毫无保留地分享给大家,让你少走弯路。
一、Flex布局
1.1 为什么Flex布局是移动端首选?
传统布局的痛点:
/* 传统方式实现垂直居中 */
.container {position: relative;height: 400px;
}
.center {position: absolute;top: 50%;left: 50%;width: 200px;height: 100px;margin-top: -50px; /* 需要计算 */margin-left: -100px; /* 需要计算 */
}
Flex布局:
/* Flex布局实现垂直居中 */
.container {display: flex;justify-content: center;align-items: center;height: 400px;
}
.center {width: 200px;height: 100px;
}
从对比中不难看出,Flex布局用更少的代码、更清晰的逻辑解决了复杂的布局问题。
1.2 Flex布局的核心概念
为了更好地理解Flex布局,我们先来看一下它的基本模型:
Flex容器 (display: flex)
├─────────────────────────────────┤
│ 主轴方向 (flex-direction) → │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ │ 元素1 │ │ 元素2 │ │ 元素3 │ ← Flex元素
│ └─────────┘ └─────────┘ └─────────┘
│ │
│ ↑ │
│ 交叉轴方向 │
└─────────────────────────────────┘
Flex布局的两大核心:
- 容器:设置
display: flex的元素,控制内部项目的布局 - 元素:容器的直接子元素,受容器属性控制
1.3 容器属性
1.3.1 flex-direction:布局方向
这个属性决定了元素的排列方向,是Flex布局的基础:
.container {/* 水平方向,从左到右(默认) */flex-direction: row;/* 水平方向,从右到左 */flex-direction: row-reverse;/* 垂直方向,从上到下 */flex-direction: column;/* 垂直方向,从下到上 */flex-direction: column-reverse;
}
实际应用场景分析:
| 属性值 | 适用场景 |
|---|---|
row | 水平导航、卡片列表 |
column | 表单布局、设置页面 |
row-reverse | 阿拉伯语等从右向左语言 |
column-reverse | 聊天界面(最新消息在底部) |
1.3.2 justify-content:主轴对齐
这个属性控制元素在主轴上的对齐方式,使用频率非常高:
.container {display: flex;/* 起始位置对齐 */justify-content: flex-start;/* 末尾位置对齐 */justify-content: flex-end;/* 居中对齐 */justify-content: center;/* 两端对齐,项目间隔相等 */justify-content: space-between;/* 每个项目两侧间隔相等 */justify-content: space-around;/* 均匀分布,包括两端 */justify-content: space-evenly;
}
空间分布对比关系:
- start - 从头开始
- end - 从尾开始
- center - 居中对齐
- between - 元素"之间"有间隔
- around - 每个元素"周围"有空间
- evenly - 所有空间"均匀"分布
1.3.3 align-items:交叉轴对齐
控制元素在交叉轴上的对齐方式:
.container {display: flex;height: 300rpx; /* 需要明确高度 *//* 交叉轴起点对齐 */align-items: flex-start;/* 交叉轴终点对齐 */align-items: flex-end;/* 交叉轴中点对齐 */align-items: center;/* 基线对齐(文本相关) */align-items: baseline;/* 拉伸填充(默认) */align-items: stretch;
}
温馨提示:align-items的效果与flex-direction密切相关:
- 当
flex-direction: row时,交叉轴是垂直方向 - 当
flex-direction: column时,交叉轴是水平方向
1.4 元素属性
1.4.1 flex-grow
控制元素放大比例,默认0(不放大):
.item {flex-grow: <number>; /* 默认0 */
}
计算原理:
总剩余空间 = 容器宽度 - 所有元素宽度总和
每个元素分配空间 = (元素的flex-grow / 所有元素flex-grow总和) × 总剩余空间
示例分析:
.container {width: 750rpx;display: flex;
}
.item1 { width: 100rpx; flex-grow: 1; }
.item2 { width: 100rpx; flex-grow: 2; }
.item3 { width: 100rpx; flex-grow: 1; }/* 计算过程:
剩余空间 = 750 - (100+100+100) = 450rpx
flex-grow总和 = 1+2+1 = 4
item1分配 = (1/4)×450 = 112.5rpx → 最终宽度212.5rpx
item2分配 = (2/4)×450 = 225rpx → 最终宽度325rpx
item3分配 = (1/4)×450 = 112.5rpx → 最终宽度212.5rpx
*/
1.4.2 flex-shrink
控制元素缩小比例,默认1(空间不足时缩小):
.item {flex-shrink: <number>; /* 默认1 */
}
小技巧:设置flex-shrink: 0可以防止元素被压缩,常用于固定宽度的元素。
1.4.3 flex-basis
定义元素在分配多余空间之前的初始大小:
.item {flex-basis: auto | <length>; /* 默认auto */
}
1.4.4 flex
flex是flex-grow、flex-shrink和flex-basis的简写:
.item {/* 等价于 flex: 0 1 auto */flex: none;/* 等价于 flex: 1 1 0% */ flex: 1;/* 等价于 flex: 1 1 auto */flex: auto;/* 自定义 */flex: 2 1 200rpx;
}
1.5 完整页面布局实现
让我们用Flex布局实现一个典型的移动端页面:
<view class="page-container"><!-- 顶部导航 --><view class="header"><view class="nav-back">←</view><view class="nav-title">商品详情</view><view class="nav-actions">···</view></view><!-- 内容区域 --><view class="content"><!-- 商品图 --><view class="product-image"><image src="/static/product.jpg" mode="aspectFit"></image></view><!-- 商品信息 --><view class="product-info"><view class="product-name">高端智能手机 8GB+256GB</view><view class="product-price"><text class="current-price">¥3999</text><text class="original-price">¥4999</text></view><view class="product-tags"><text class="tag">限时优惠</text><text class="tag">分期免息</text><text class="tag">赠品</text></view></view><!-- 规格选择 --><view class="spec-section"><view class="section-title">选择规格</view><view class="spec-options"><view class="spec-option active">8GB+256GB</view><view class="spec-option">12GB+512GB</view></view></view></view><!-- 底部操作栏 --><view class="footer"><view class="footer-actions"><view class="action-btn cart">购物车</view><view class="action-btn buy-now">立即购买</view></view></view>
</view>
.page-container {display: flex;flex-direction: column;height: 100vh;background-color: #f5f5f5;
}/* 头部导航 */
.header {display: flex;align-items: center;justify-content: space-between;height: 88rpx;