一.海报轮播图制作
使用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>
实现效果:
二.纵向轮播来做公告区域
和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;
}
}
}
}
实现效果:
三.每日推荐滑动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>
实现效果:
四.专题精选
网格布局实现:
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"
}
]
}