uniapp学习day7

98 阅读3分钟

一.海报轮播图制作

使用swiper来制作,swiper-item就是每一张图片,要注意的是css样式,这里是比较难的地方

common-style:

view,swiper,swiper-item {
	box-sizing:border-box;
}

index.vue:

设置indicator,设置各个盒子的大小以及上下边距,左右边距

<template>
	<view class="homeLayout">
		<view class="banner">
			<swiper indicator-dots indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#fff" autoplay circular>
				<swiper-item>
					<image src="../../common/images/banner1.jpg" mode="aspectFill"></image>
				</swiper-item>
				<swiper-item>
					<image src="../../common/images/banner2.jpg" mode="aspectFill"></image>
				</swiper-item>
				<swiper-item>
					<image src="../../common/images/banner3.jpg" mode="aspectFill"></image>
				</swiper-item>
			</swiper>
		</view>
	</view>
		
</template>

<script setup>
	
</script>

<style lang="scss" scoped>
	.homeLayout {
		.banner {
			width: 750rpx;
			padding: 30rpx 0;
			swiper {
				width: 750rpx;
				height: 340rpx;
				&-item{
					width: 100%;
					height: 100%;
					padding:0 30rpx;
				}
				image {
					width: 100%;
					height: 100%;
					border-radius: 10rpx;
				}
			}
		}
	}
</style>

实现效果:

image.png

二.纵向轮播来做公告区域

和banner在同一级中:分为左中右

<view class="notice">
			<view class="left">
				<uni-icons type="sound-filled" size="20" color="#28b389"></uni-icons>
                <text>公告</text>
			</view>
			<view class="center">
				<swiper vertical autoplay interval="1500" duration="300" circular>
					<swiper-item>
						文字内容
					</swiper-item>
					<swiper-item>
						文字内容文字内容文字内容文字内容文字内容文字内容
					</swiper-item>
					<swiper-item>
						文字内容
					</swiper-item>
				</swiper>
			</view>
			
			<view class="right">
				<uni-icons type="right" size="16" color="#999"></uni-icons>
			</view>
		</view>

重点还是布局上: 给notice添加display:flex,固定两边的宽度,中间使用flex自动分配

在每个部分中,通过设置

display: flex; align-items: center; justify-content: center;

让区域中的元素居中分配

.notice {
			width: 690rpx;
			height: 80rpx;
			line-height: 80rpx;
			background-color: #f9f9f9;
			margin: 0 auto;
			border-radius: 80rpx;
			display: flex;
			
			.left {
				width: 140rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				text {
					color: #28b389;
				}
			}
			.right {
				width: 70rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				
			}
			.center {
				flex: 1;
				swiper {
					height: 100%;
					swiper-item {
						height: 100%;
						color:#666;
						overflow: hidden;
						white-space: nowrap;
						text-overflow: ellipsis;
					}
				}
			}
		}

实现效果:

image.png

三.每日推荐滑动scroll-view布局

先新建一个标题组件,后面就不用重写了<common-title></common-title>

scroll-view设置成scroll-x,横向滑动,里面的每一项就是一个view,和swiper不一样,没有item

<view class="select">
			<common-title></common-title>
			<view class="content">
				<scroll-view scroll-x>
					<view class="box">
						<image src="../../common/images/preview_small.webp" mode="aspectFill"></image>
					</view>
					<view class="box">
						<image src="../../common/images/preview_small.webp" mode="aspectFill"></image>
					</view>
					<view class="box">
						<image src="../../common/images/preview_small.webp" mode="aspectFill"></image>
					</view>
					<view class="box">
						<image src="../../common/images/preview_small.webp" mode="aspectFill"></image>
					</view>
				</scroll-view>
			</view>
		</view>

css:

scroll-view设置成不换行 white-space: nowrap;

每个图片的盒子设置成行内块元素,就能放在一行展示了display: inline-block;

.select {
			padding-top: 50rpx;
			
			.content {
				padding-top: 30rpx;
				width: 720rpx;
				margin-left: 30rpx;
				scroll-view {
					white-space: nowrap;
					.box {
						width: 200rpx;
						height: 430rpx;
						display: inline-block;
						margin-right: 15rpx;
                        image {
							width: 100%;
							height: 100%;
							border-radius: 10rpx;
						}
					}
					.box:last-child {
						margin-right: 30rpx;
					}
				}
			}
		}

现在来完善组件的具名插槽:

display: flex; justify-content: space-between; align-items: center;

justify-content: space-between; 作用是让盒子中的元素放到两边对齐

<template>
	<view class="common-title">
		<view class="name">
			<slot name="nameslot"></slot>
		</view>
		<view class="custom">
			<slot name="customslot"></slot>
		</view>
	</view>
</template>

<script setup>
	
</script>

<style lang="scss" scoped>
.common-title {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 0 30rpx;
	.name {
		font-size: 40rpx;
		
	}
	
}
</style>

使用:用template以及#name来设置具名插槽

<common-title>
			  <template #nameslot>
			  	<view>每日推荐</view>
			  </template>
			  <template #customslot>
				  <view class="date">
					 
				  	<uni-icons type="calendar" size="18" color="#28b389"></uni-icons>
					<view class="text">
						<uni-dateformat :date="Date.now()" format="dd"></uni-dateformat>
					</view>
				  </view>
			  </template>
			</common-title>

实现效果:

image.png

四.专题精选

网格布局实现:

display: grid;

gap:15rpx;

grid-template-columns:repeat(3,1fr);

<view class="theme">
			<common-title>
			  <template #nameslot>
			  	<view>专题精选</view>
			  </template>
			  <template #customslot>
				 <navigator url="" class="more">More+</navigator>
			  </template>
			</common-title>
			<view class="content">
				<theme-item v-for="item in 8"></theme-item>
				<theme-item :isMore="true"></theme-item>
			</view>
		</view>

css:

.theme {
		     padding: 50rpx 0;
			 .more {
				 font-size: 32rpx;
				 color: #888;
			 }
			 .content {
				 width: 750rpx;
				 margin-top: 30rpx;
				 padding:0 30rpx;
				 display: grid;
				 gap:15rpx;
				 grid-template-columns:repeat(3,1fr);
			 }
		}

完善theme-item组件:

这里用到了透明磨砂背景设置:background:rgb(250, 129, 90,0.7); backdrop-filter: blur(20rpx);

还有more中取消之前设置的display:flex; :flex-direction: column;

又用到了子元素布局 display: flex; align-items: center; justify-content: center;

<template>
	<view class="themeItem">
		<navigator url="" class="box" v-if="!isMore">
			<image class="pic" src="../../common/images/classify1.jpg" mode="aspectFill"></image>
			<view class="text"></view>
			<view class="mask">美女</view>
			<view class="tab">3天前更新</view>
		</navigator>
		
		<navigator url="" class="box more" v-if="isMore">
			<image class="pic" src="../../common/images/classify2.jpg" mode="aspectFill"></image>
			<view class="text"></view>
			
			<view class="mask">
				<uni-icons type="more-filled" size="30" color="#fff" ></uni-icons>
                <view class="text">更多</view>
			</view>
			
		</navigator>
	</view>
</template>

<script setup>
	defineProps({
		isMore:{
			type:Boolean,
			default:false
		}
	})
	
</script>

<style lang="scss" scoped>
.themeItem {
	.box {
		height: 340rpx;
		border-radius: 10rpx;
		overflow: hidden;
		position: relative;
		.pic {
			width: 100%;
		}
		.mask {
			
			width: 100%;
			height: 70rpx;
			position: absolute;
			left: 0;
			bottom: 0;
			background: rgba(0,0,0,0.2);
			color: #fff;
			font-weight: 600;
			font-size: 30rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			backdrop-filter: blur(20rpx);
			
		}
		.tab {
			position: absolute;
			left: 0;
			top: 0;
			background:rgb(250, 129, 90,0.7);
			backdrop-filter: blur(20rpx);
			color: #fff;
			font-size: 20rpx;
			padding: 6rpx 10rpx;
			border-radius: 0 0 20rpx 0;
		}
	}
	.box.more {
		.mask {
			width: 100%;
			height: 100%;
			background: rgba(0,0,0,0.2);
		    backdrop-filter: blur(20rpx);
			flex-direction: column;
		}
	}
		
	}
</style>

五.分类页面

使用和前面一样的网格布局去放theme-item组件:

display: grid; grid-template-columns:repeat(3,1fr); gap:15rpx;

<template>
	<view class="classLayout">
		<view class="classify">
			<theme-item v-for="item in 15"></theme-item>
		</view>
	</view>
</template>

<script setup>
	
</script>

<style lang="scss" scoped>
.classLayout {
	.classify {
		padding: 30rpx;
		display: grid;
		grid-template-columns:repeat(3,1fr);
		gap:15rpx;
	}
	
}
</style>

六.tabBar

在pages.json中设置:

"tabBar": {
		"list": [
			{
				"text": "推荐",
				"pagePath": "pages/index/index",
				"iconPath": "/static/home.png",
				"selectedIconPath": "/static/home-h.png"
			},
			{
				"text":"分类",
				"pagePath": "pages/classify/classify",
				"iconPath": "/static/classify.png",
				"selectedIconPath": "/static/classify-h.png"
			},
			{
				"text":"我的",
				"pagePath": "pages/user/user",
				"iconPath": "/static/user.png",
				"selectedIconPath": "/static/user-h.png"
			}
		]
	}