uni-app开发微信小程序系列之--样式与flex布局

2,958 阅读10分钟

上一节: uni-app开发微信小程序系列之--框架基础

flex布局

不论是支付宝, 还是微信等小程序都是推荐使用flex布局的. flex布局会有后面的章节以及示例项目中都有贯穿使用.

flex布局的概念

  • flexible box: 弹性盒状布局
  • 容器控制内部元素的布局定位
  • CSS3引入的新布局模型
  • 伸缩元素,自由填充,自适应

使用flex布局的优势

  • 可在不同方向排列元素
  • 控制元素排序的方向
  • 控制元素的对齐方式
  • 控制元素之间等矩
  • 控制单个元素放大与缩放比例,占比,对齐方式

flex常用术语

  • flex container, flex容器
  • flex item, flex元素
  • flex direction, 布局方向

flex布局模型

主轴和交叉轴也可以交换方向

flex属性

flex-direction, 设置元素的排列方向

  • row
  • row-reverse
  • column
  • column-reverse

示例代码

<template>
	<view class="container">
		<view class="green txt">
			green
		</view>
		<view class="red txt">
			red
		</view>
		<view class="blue txt">
			blue
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 20px;
	width: 300upx;
	height: 300upx;
}
</style>

row, row-reverse

flex-direction: row 效果

flex-direction: row-reverse 效果

column, column-reverse

flex-direction: column 效果

flex-direction: column-reverse 效果

flex-wrap, 使容器内的元素换行

  • nowrap, (默认值)不换行, 多个元素时, 会做一定的缩放
  • wrap
  • wrap-reverse

示例代码

修改下上面的示例代码:

.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
}

nowrap 效果

wrap 效果

wrap-reverse 效果

justify-content, 设置元素在主轴上的对齐方式

justify-content, 定义了flex容器中flex成员项在主轴方向上如何排列以处理空白部分, 默认为flex-start

  • flex-start, (默认值)左对齐或向上对齐
  • flex-end, 右对齐或向下对齐
  • center, 居中对齐
  • space-between, 两端对齐, 元素之间平均等分剩余空白间隙部分
  • space-around, 元素两边平均等分剩余空白间隙部分, 最左(最上)或最右(最下)和元素之间的距离比是1:2

示例代码

修改如上示例代码:

.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: flex-start;
}

flex-start, (默认值)左对齐或向上对齐

flex-end, 右对齐或向下对齐

center, 居中对齐

space-between, 两端对齐, 元素之间平均等分剩余空白间隙部分

space-around, 元素两边平均等分剩余空白间隙部分, 最左(最上)或最右(最下)和元素之间的距离比是1:2

align-items, 设置元素在交叉轴上的对齐方式

  • stretch, (默认)当元素的高度没有设置时, 元素的高度会被拉伸并与容器高度一致
  • flex-start, 在交叉轴上向起点位置(向上/向左)对齐
  • flex-end, 在交叉轴上向结束位置(向下/向右)对齐
  • center, 居中对齐
  • baseline, 保证元素中的文字在同一条基准线上(保证每个文字都在同一条线上)

示例代码

<template>
	<view class="container">
		<view class="green txt" style="height: 200upx;font-size: 30px;">
			green1
		</view>
		<view class="red txt" style="font-size: 10px;">
			red1
		</view>
		<view class="blue txt" style="height: 300upx;font-size: 50px;">
			blue1
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: flex-start;
	height: 800upx;
	background-color: #F8F8F8;
	align-items: stretch;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 20px;
/* 	width: 100upx;
	height: 100upx; */
}
</style>

stretch, (默认)当元素的高度没有设置时, 元素的高度会被拉伸并与容器高度一致

flex-start, 在交叉轴上向起点位置(向上/向左)对齐

flex-end, 在交叉轴上向结束位置(向下/向右)对齐

center, 居中对齐

baseline, 保证元素中的文字在同一条基准线上(保证每个文字都在同一条线上)

align-content, 设置轴线的对齐方式(轴线当做元素)

  • stretch,(默认值)
  • flex-start
  • flex-end
  • center
  • space-between
  • space-around

示例代码:

<template>
	<view class="container">
		<view class="green txt">
			green1
		</view>
		<view class="red txt">
			red1
		</view>
		<view class="blue txt">
			blue1
		</view>
		<view class="green txt">
			green2
		</view>
		<view class="red txt">
			red2
		</view>
		<view class="blue txt">
			blue2
		</view>
		<view class="green txt">
			green3
		</view>
		<view class="red txt">
			red3
		</view>
		<view class="blue txt">
			blue3
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: column;
	flex-wrap: wrap;
	align-content: stretch;
	height: 150px;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 20upx;
	width: 60upx;
	height: 60upx;
}
</style>

stretch, 拉伸

当width/height没有设置时, 轴线可以被拉伸 修改下代码:

.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: column;
	flex-wrap: wrap;
	align-content: stretch;
	height: 300upx;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 20px;
	/* width: 60upx; */ // 注释此行代码
	height: 60upx;
}

因为flex-direction: column;纵向是主轴, 因此需要将flex item的width注释掉. 效果如下

center, 居中

当轴线超过1条时, flex容器可以把多条轴线视为元素对待, 进行对齐

flex-start, 向上/向左对齐

flex-end, 向下/向右对齐

space-between, 两端对齐

元素之间的空白等比切分

space-around

轴线两边的空白等比切分

flex元素的属性

order, 控制元素的顺序

  • 用于设置flex容器内的每个元素的排列顺序
  • 排序规则: 由小到大
  • 默认值为 0

示例代码:

<template>
	<view class="container">
		<view class="green txt">
			green1
		</view>
		<view class="red txt">
			red1
		</view>
		<view class="blue txt">
			blue1
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	height: 800upx;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 20px;
	width: 200upx;
	height:200upx;
}
</style>

默认情况下, order值为0, 效果如下:

修改代码如下:

.green{
	background-color: #4CD964;
	order: 3;
}
.red{
	background-color: red;
	order: 2;
}
.blue{
	background-color: blue;
	order: 1;
}

效果如下:

flex-grow, 控制元素放大比例

  • 默认值为 0
  • 用于设置元素的放大比例, 若为0, 则不放大.

使用前提: 撑满剩余的空间

修改如上代码如下:

.green{
	background-color: #4CD964;
	order: 3;
	flex-grow: 0;
}
.red{
	background-color: red;
	order: 2;
	flex-grow: 0;
}
.blue{
	background-color: blue;
	order: 1;
	flex-grow: 0;
}

效果如下:

.red设置flex-grow: 1

.red{
	background-color: red;
	order: 2;
	flex-grow: 1;
}

效果如下:

若将其他两个元素也设置同样的值: flex-grow: 1

.green{
	background-color: #4CD964;
	order: 3;
	flex-grow: 1;
}
.red{
	background-color: red;
	order: 2;
	flex-grow: 1;
}
.blue{
	background-color: blue;
	order: 1;
	flex-grow: 1;
}

将会发现, 这3个元素的放大后的比例是一致的. 即将剩余空间进行等比例平分了.

更进一步的, 若修改代码:

.red{
	background-color: red;
	order: 2;
	flex-grow: 2;
}

则空间划分比例为: 1:2:1, 效果如下:

flex-shrink, 控制元素缩小的比例

  • 默认值为 1, 当设置为0时, 不进行缩放
  • 用于定义元素的缩放比例

使用前提: 当前的空间已满, 需要进行缩放

为更好的呈现出效果, 多增加flex元素, 修改后, 代码如下:

<template>
	<view class="container">
		<view class="green txt">
			green1
		</view>
		<view class="red txt">
			red1
		</view>
		<view class="blue txt">
			blue1
		</view>
		<view class="green txt">
			green2
		</view>
		<view class="red txt">
			red2
		</view>
		<view class="blue txt">
			blue2
		</view>
		<view class="green txt">
			green3
		</view>
		<view class="red txt">
			red3
		</view>
		<view class="blue txt">
			blue3
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	height: 800upx;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 12px;
	width: 200upx;
	height:200upx;
}
</style>

效果如下:

.red的``设置为0时

.red{
	background-color: red;
	flex-shrink: 0;
}

可以看到如下效果:

若其他元素, 也不进行缩放, 即: flex-shrink: 0;

.green{
	background-color: #4CD964;
	flex-shrink: 0;
}
.red{
	background-color: red;
	flex-shrink: 0;
}
.blue{
	background-color: blue;
	flex-shrink: 0;
}

则多余的元素可能会被放到外边界了, 效果如下:

flex-basis, 设置元素固定或自动空间的占比

示例代码:

<template>
	<view class="container">
		<view class="green txt">
			green1
		</view>
		<view class="red txt">
			red1
		</view>
		<view class="blue txt">
			blue1
		</view>
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	height: 800upx;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 12px;
	width: 200upx;
	height:200upx;
}
</style>

当前效果如下:

这里我们单独将.red进行放大

.red{
	background-color: red;
	flex-basis: 300upx;
}

当然, 也可以进行缩放, .red元素会使用.txt的宽度200upx, 这里我们进行缩小

.red{
	background-color: red;
	flex-basis: 100upx;
}
.txt{
	font-size: 12px;
	width: 200upx;
	height:200upx;
}

align-self, 重写align-items父属性

  • auto, 默认值, 表示继承父级元素的align-items属性值
  • stretch, 当元素的高度没有设置时, 元素的高度会被拉伸并与容器高度一致
  • flex-start, 在交叉轴上向起点位置(向上/向左)对齐
  • flex-end, 在交叉轴上向结束位置(向下/向右)对齐
  • center, 居中对齐
  • baseline, 保证元素中的文字在同一条基准线上(保证每个文字都在同一条线上)

示例代码

<template>
	<view class="container">
		<view class="green txt" style="height: 200upx;font-size: 30px;">
			green1
		</view>
		<view class="red txt" style="font-size: 10px;">
			red1
		</view>
		<view class="blue txt" style="height: 300upx;font-size: 50px;">
			blue1
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style>
.container{
	/* 定义flex容器 */
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: flex-start;
	height: 800upx;
	background-color: #F8F8F8;
	align-items: baseline;
}
.green{
	background-color: #4CD964;
}
.red{
	background-color: red;
}
.blue{
	background-color: blue;
}
.txt{
	font-size: 20px;
/* 	width: 100upx;
	height: 100upx; */
}
</style>

当前align-items: baseline, 效果图如下:

若不想让red1向上或向下对齐, 该怎么处理呢? 修改代码如下:

.red{
	background-color: red;
	align-self: flex-start;
}

可以看到.red是向上对齐的

也可以改为:

.red{
	background-color: red;
	align-self: center;
}

效果图如下:

若将.red修改为align-self: stretch;会怎么样呢? 需要注意的是, 要将.red不设置高度, 否则会不生效. 修改代码如下:

		<view class="red" style="font-size: 10px;">
			red1
		</view>

同时修改css

.red{
	background-color: red;
	align-self: stretch;
}

最终效果如下:

下一节: uni-app开发微信小程序系列之--项目实战-首页开发