首页模板
一、轮播图部分
使用的京东的轮播图图片
页面布局部分
<!-- 轮播图部分 -->
<swiper class="swiper-home" indicator-dots="true" autoplay="true" interval="2000"
circular="true" indicator-color="#000" indicator-active-color="#FF0000">
<swiper-item v-for="(item,index) in bannerList" :key="index">
<image :src="item.picUrl"></image>
</swiper-item>
</swiper>
页面样式
使用的scss
.swiper-home{
width:100%;
background-color: #fff;
swiper-item{
width:100%;
image{
width:100%;
height:300rpx;
}
}
}
后台数据
连接后台
<script>
export default {
data() {
return {
//定义一个存放轮播图数据的空数组
bannerList:[]
};
},
methods:{
getBannerList:async function(){
const res=await uni.$http.get('/bannerlist');
// console.log(res)
// 解构
const {data:{list},code}=res.data
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.bannerList=list
}
}
},
// 页面一进来就加载
onLoad(){
this.getBannerList()
}
}
</script>
效果图:
二、分类
页面布局部分
<!-- 分类部分 -->
<view class="cates">
<view class="cate-item" v-for="(cateItem,cateIndex) in cateList"
:key="cateIndex">
<image :src="cateItem.cateUrl"></image>
<text>{{cateItem.cateName}}</text>
</view>
</view>
页面样式
.cates{
width: 100%;
height: 200rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-around;
.cate-item{
width: 20%;
height: 160rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
image{
width: 100rpx;
height: 100rpx;
}
}
}
后台数据
连接后台
<script>
export default {
data() {
return {
。。。
// 定义一个空数组存放分类数据
cateList:[]
};
},
methods:{
。。。
// 获取分类信息
getCateList:async function(){
const res=await uni.$http.get('/cates')
console.log(res)
const {data:{cateList},code}=res.data
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.cateList=cateList
}
}
},
// 页面一进来就加载
onLoad(){
。。。
//调用获取分类数据的方法
this.getCateList()
}
}
</script>
效果图:
三、限时秒购部分
页面布局
<!-- 限时秒购部分 -->
<view class="time">
<view class="timeTop">
<view class="logo">
<image src="/static/images/闹钟.png" mode=""></image>
<text>限时秒购</text>
</view>
<view class="timeFinish">
<text>距结束</text>
<uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-
countdown>
</view>
</view>
<view class="timeBottom">
<view class="timeItem" v-for="(timeItem,timeIndex) in timeList"
:key="timeIndex">
<image :src="timeItem.timeUrl"></image>
<view class="timeText">
<text class="timeText1">¥{{timeItem.timeText1}}</text>
<text class="timeText2">¥{{timeItem.timeText2}}</text>
</view>
</view>
</view>
</view>
页面样式
.time{
width: 100%;
background-color: #fff;
margin-top: 20rpx;
.timeTop{
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 20rpx;
.logo{
image{
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
text{
font-size: 16px;
}
}
.timeFinish{
margin-right: 20rpx;
display: flex;
align-items: center;
text{
font-size: 14px;
}
}
}
.timeBottom{
width: 100%;
display: flex;
justify-content: space-around;
.timeItem{
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
image{
width: 160rpx;
height: 160rpx;
}
.timeText{
display: flex;
justify-content: space-between;
font-size: 14px;
.timeText2{
color: #9F9F9F;
text-decoration:line-through;
}
}
}
}
}
后台数据
连接后台
<script>
export default {
data() {
return {
。。。
// 定义一个空数组存放限时秒购数据
timeList:[]
};
},
methods:{
。。。
// 获取限时秒购信息
getTimeList:async function(){
const res=await uni.$http.get('/time')
console.log(res)
const {data:{timeList},code}=res.data
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.timeList=timeList
}
}
},
// 页面一进来就加载
onLoad(){
。。。
//调用获取限时秒购的方法
this.getTimeList()
}
}
</script>
效果图:
四、商品列表部分
页面布局
<!-- 商品部分 -->
<view class="shop">
<view class="shop-top">
<view :class="['shop-item',activeIndex==shopIndex?'active':''] " v-for="(shopItem,shopIndex) in shopList"
:key="shopIndex" @click="changeActive(shopIndex)">{{shopItem.shopName}}</view>
</view>
<view class="shop-bottom">
<view class="shop-content" v-for="(goodItem,goodIndex) in goodsList" :key="goodIndex">
<image :src="goodItem.picUrl" mode=""></image>
<view class="shop-title">{{goodItem.pname}}</view>
<view class="shop-price">
<text class="nowprice">¥{{goodItem.price}}</text>
<text class="afterprice">¥{{goodItem.afterprice}}</text>
</view>
</view>
</view>
</view>
页面样式
.shop{
width: 100%;
margin-top: 20rpx;
background-color: #fff;
.shop-top{
width: 100%;
height: 100rpx;
// background-color: #007AFF;
border: 1px solid #F0F0F0;
display: flex;
justify-content: space-around;
align-items: center;
.shop-item{
font-size: 18px;
color: #676767;
padding-bottom: 20rpx;
}
.active{
font-size: 20px;
color: black;
position: relative;
//&拿到上级选择器
&::after{
content: '';
display: block;
height: 10rpx;
width: 50rpx;
border-radius: 4rpx;
background-color: #FE5348;
position: absolute;
bottom: 0rpx;
left: 10rpx;
}
}
}
.shop-bottom{
width: 100%;
display: flex;
justify-content:space-around;
margin-top: 20rpx;
flex-wrap: wrap;
.shop-content{
width: 45%;
image{
width: 340rpx;
height: 360rpx;
}
.shop-title{
width: 340rpx;
font-size: 18px;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.shop-price{
margin-top: 20rpx;
.nowprice{
color: #FD4E4C;
font-size: 26px;
font-weight: bold;
}
.afterprice{
font-size: 18px;
color: #666666;
text-decoration:line-through;
}
}
}
}
}
后台数据
连接后台
<script>
export default {
data() {
return {
。。。
// 初始化的商品列表
shopList:[],
//当前点击项的索引号
activeIndex:0,
// 分类下的商品信息
goodsList:[]
};
},
methods:{
。。。
//获取商品列表信息
async getshopList(){
const res =await uni.$http.get('/shop')
const {data:{shopList},code}=res.data
// console.log(shopList,code)
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.shopList=shopList
// 获取第一个分类下的商品
this.goodsList=shopList[0].children
}
console.log(this.goodsList)
},
//动态更换当前激活的索引号
changeActive(i){
this.activeIndex=i
// 已经获取了你点的那个类的索引号
this.goodsList=this.shopList[i].children
}
},
// 页面一进来就加载
onLoad(){
。。。
//调用获取商品列表信息的方法
this.getshopList()
}
}
</script>
效果图:
整体代码
<template>
<view>
<!-- 轮播图部分 -->
<swiper class="swiper-home" indicator-dots="true" autoplay="true" interval="2000"
circular="true" indicator-color="#000" indicator-active-color="#FF0000">
<swiper-item v-for="(item,index) in bannerList" :key="index">
<image :src="item.picUrl"></image>
</swiper-item>
</swiper>
<!-- 分类部分 -->
<view class="cates">
<view class="cate-item" v-for="(cateItem,cateIndex) in cateList" :key="cateIndex">
<image :src="cateItem.cateUrl"></image>
<text>{{cateItem.cateName}}</text>
</view>
</view>
<!-- 限时秒购部分 -->
<view class="time">
<view class="timeTop">
<view class="logo">
<image src="https://s1.ax1x.com/2022/03/17/qC82se.png" mode=""></image>
<text>限时秒购</text>
</view>
<view class="timeFinish">
<text>距结束</text>
<uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
</view>
</view>
<view class="timeBottom">
<view class="timeItem" v-for="(timeItem,timeIndex) in timeList" :key="timeIndex">
<image :src="timeItem.timeUrl"></image>
<view class="timeText">
<text class="timeText1">¥{{timeItem.timeText1}}</text>
<text class="timeText2">¥{{timeItem.timeText2}}</text>
</view>
</view>
</view>
</view>
<!-- 商品部分 -->
<view class="shop">
<view class="shop-top">
<view :class="['shop-item',activeIndex==shopIndex?'active':''] " v-for="(shopItem,shopIndex) in shopList"
:key="shopIndex" @click="changeActive(shopIndex)">{{shopItem.shopName}}</view>
</view>
<view class="shop-bottom">
<view class="shop-content" v-for="(goodItem,goodIndex) in goodsList" :key="goodIndex">
<image :src="goodItem.picUrl" mode=""></image>
<view class="shop-title">{{goodItem.pname}}</view>
<view class="shop-price">
<text class="nowprice" style="font-size: 40rpx;">¥{{goodItem.price}}</text>
<text class="afterprice" style="font: 30rpx;">¥{{goodItem.afterprice}}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//定义一个存放轮播图数据的空数组
bannerList:[],
// 定义一个空数组存放分类数据
cateList:[],
// 定义一个空数组存放限时秒购数据
timeList:[],
// 初始化的商品列表
shopList:[],
//当前点击项的索引号
activeIndex:0,
// 分类下的商品信息
goodsList:[]
};
},
methods:{
//获取轮播图列表
getBannerList:async function(){
const res=await uni.$http.get('/bannerlist');
// console.log(res)
// 解构
const {data:{list},code}=res.data
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.bannerList=list
}
},
// 获取分类信息
getCateList:async function(){
const res=await uni.$http.get('/cates')
// console.log(res)
const {data:{cateList},code}=res.data
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.cateList=cateList
}
},
// 获取限时秒购信息
getTimeList:async function(){
const res=await uni.$http.get('/time')
// console.log(res)
const {data:{timeList},code}=res.data
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.timeList=timeList
}
},
//获取商品列表信息
async getshopList(){
const res =await uni.$http.get('/shop')
const {data:{shopList},code}=res.data
// console.log(shopList,code)
if(code!=200){
return uni.showToast({
title:'加载数据失败',
duration:1000,
icon:'none'
})
}else{
this.shopList=shopList
// 获取第一个分类下的商品
this.goodsList=shopList[0].children
}
console.log(this.goodsList)
},
//动态更换当前激活的索引号
changeActive(i){
this.activeIndex=i
// 已经获取了你点的那个类的索引号
this.goodsList=this.shopList[i].children
}
},
// 页面一进来就加载
onLoad(){
// 调用获取轮播图数据的方法
this.getBannerList()
//调用获取分类数据的方法
this.getCateList()
//调用获取限时秒购的方法
this.getTimeList()
//调用获取商品列表信息的方法
this.getshopList()
}
}
</script>
<style lang="scss">
*{
margin: 0;
padding: 0;
}
.swiper-home{
width:100%;
height: 300rpx;
background-color: #fff;
swiper-item{
width:100%;
image{
width:100%;
height:300rpx;
}
}
}
.cates{
width: 100%;
height: 200rpx;
display: flex;
align-items: center;
justify-content: space-around;
background-color: #fff;
.cate-item{
width: 20%;
height: 160rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
image{
width: 100rpx;
height: 100rpx;
}
}
}
.time{
width: 100%;
background-color: #fff;
margin-top: 20rpx;
.timeTop{
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 20rpx;
.logo{
image{
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
text{
font-size: 16px;
}
}
.timeFinish{
margin-right: 20rpx;
display: flex;
align-items: center;
text{
font-size: 14px;
}
}
}
.timeBottom{
width: 100%;
display: flex;
justify-content: space-around;
.timeItem{
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
image{
width: 160rpx;
height: 160rpx;
}
.timeText{
display: flex;
justify-content: space-between;
font-size: 14px;
.timeText2{
color: #9F9F9F;
text-decoration:line-through;
}
}
}
}
}
.shop{
width: 100%;
margin-top: 20rpx;
background-color: #fff;
.shop-top{
width: 100%;
height: 100rpx;
// background-color: #007AFF;
border: 1px solid #F0F0F0;
display: flex;
justify-content: space-around;
align-items: center;
.shop-item{
font-size: 18px;
color: #676767;
padding-bottom: 20rpx;
}
.active{
font-size: 20px;
color: black;
position: relative;
//&拿到上级选择器
&::after{
content: '';
display: block;
height: 10rpx;
width: 50rpx;
border-radius: 4rpx;
background-color: #FE5348;
position: absolute;
bottom: 0rpx;
left: 10rpx;
}
}
}
.shop-bottom{
width: 100%;
display: flex;
justify-content:space-around;
margin-top: 20rpx;
flex-wrap: wrap;
.shop-content{
width: 45%;
image{
width: 340rpx;
height: 360rpx;
}
.shop-title{
width: 340rpx;
font-size: 18px;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.shop-price{
margin-top: 20rpx;
.nowprice{
color: #FD4E4C;
font-size: 26px;
font-weight: bold;
}
.afterprice{
font-size: 18px;
color: #666666;
text-decoration:line-through;
}
}
}
}
}
</style>
整体效果图: