You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
485 lines
11 KiB
485 lines
11 KiB
<template>
|
|
<BaseContainer class="store" :fixedNav="false">
|
|
<view>
|
|
<view class="swiper-box" :style="{ background: `linear-gradient(180deg, rgb(${color_one}) 0%,#F7F8F9 100%)` }">
|
|
<swiper class="custom-banner" indicator-dots autoplay
|
|
@click="handleBannerClick" @change="getChangeImage">
|
|
<swiper-item v-for="(item, index) in banner" :key="index" :data-url="item.url" class="swiper-item">
|
|
<image :data-url="item.url" mode="aspectFill" :src="item.pic" :alt="item.title" />
|
|
</swiper-item>
|
|
</swiper>
|
|
</view>
|
|
<view class="tab-bar-placeholder">
|
|
<scroll-view scroll-x class="tab-box" :class="{ fixed: tabBarFixed }" id="tabbox">
|
|
<view class="flex tab-content" @click="handleCateClick">
|
|
<view :data-idx="index" class="tab-item" v-for="(item, index) in categoryList" :key="item.id"
|
|
:class="{ on: clickedIndex === index }">{{ item.cate_name }}</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
<view class="goods-section">
|
|
<view class="list">
|
|
<navigator hover-class="none" v-for="item in goodsList" :key="item.id" class="item"
|
|
:url="'/pages/store/detail?id=' + item.id">
|
|
<view class="image">
|
|
<image mode="aspectFit" class="img" :src="item.image" alt="" />
|
|
</view>
|
|
<view class="text">
|
|
<view class="title">{{ item.store_name }}</view>
|
|
<view class="group">
|
|
<view class="price">
|
|
¥<span class="num">{{ item.price }}</span>
|
|
</view>
|
|
<view class="sale">已售{{ item.sales }}件</view>
|
|
</view>
|
|
</view>
|
|
</navigator>
|
|
</view>
|
|
<view v-if="goodsList.length && !loading" class="finished">{{ loadTitle }}</view>
|
|
<view v-if="finished && !goodsList.length" class="empty">
|
|
<image mode="aspectFill" :src="getImgPath('/wap/first/zsff/images/empty.png')" alt="暂无商品" />
|
|
<view>暂无商品</view>
|
|
</view>
|
|
<!-- <view style="height: var(--tab-bar-height)"></view> -->
|
|
</view>
|
|
</view>
|
|
</BaseContainer>
|
|
</template>
|
|
|
|
<script>
|
|
import { getCateList, getGoodsList, getIndexData } from "@/api/store";
|
|
|
|
export default {
|
|
data() {
|
|
const systemInfo = this.$util.getSystemInfo();
|
|
const { statusBarHeight } = systemInfo;
|
|
return {
|
|
statusBarHeight,
|
|
banner: [],
|
|
categoryList: [],
|
|
goodsList: [],
|
|
clickedIndex: 0,
|
|
activeId: 0,
|
|
loadTitle: "",
|
|
page: 1,
|
|
limit: 16,
|
|
loading: false,
|
|
finished: false,
|
|
isFixed: false,
|
|
offsetTop: 0,
|
|
offsetHeight: 0,
|
|
tabBarFixed: false,
|
|
tabBarTopSize: 0,
|
|
color_one: '',
|
|
color_two: '',
|
|
};
|
|
},
|
|
onLoad() {
|
|
this.handlePageScroll = this.$util.debounce(this.handlePageScroll, 30);
|
|
|
|
this.getCateList();
|
|
this.getGoodsList();
|
|
this.getIndexData();
|
|
},
|
|
onReachBottom() {
|
|
this.getGoodsList();
|
|
},
|
|
onPageScroll({ scrollTop }) {
|
|
this.handlePageScroll(scrollTop);
|
|
},
|
|
onShareAppMessage() {
|
|
return {};
|
|
},
|
|
onShareTimeline() {
|
|
return {};
|
|
},
|
|
mounted() {
|
|
const selectQuery = uni.createSelectorQuery().in(this);
|
|
selectQuery
|
|
.select("#tabbox")
|
|
.boundingClientRect(({ top }) => {
|
|
this.tabBarTopSize = top;
|
|
})
|
|
.exec();
|
|
},
|
|
methods: {
|
|
handlePageScroll(scrollTop) {
|
|
this.tabBarFixed = scrollTop + this.statusBarHeight >= this.tabBarTopSize;
|
|
},
|
|
async getIndexData() {
|
|
try {
|
|
const { data } = await getIndexData();
|
|
this.banner = data;
|
|
if(!this.color_one && !this.color_two){
|
|
this.color_one = this.banner[0].color_one;
|
|
this.color_two = this.banner[0].color_two;
|
|
}
|
|
} catch (err) { }
|
|
},
|
|
// 点击轮播图
|
|
handleBannerClick(e) {
|
|
|
|
if (e.target.dataset.url === undefined) return;
|
|
uni.navigateTo({
|
|
url: e.target.dataset.url,
|
|
});
|
|
},
|
|
getChangeImage(e) {
|
|
this.banner.forEach((item, index) => {
|
|
if (index == e.detail.current) {
|
|
this.color_one = item.color_one;
|
|
this.color_two = item.color_two;
|
|
}
|
|
});
|
|
},
|
|
// 获取分类
|
|
async getCateList() {
|
|
try {
|
|
const { data } = await getCateList();
|
|
this.categoryList = [
|
|
{
|
|
cate_name: "全部",
|
|
id: 0,
|
|
},
|
|
].concat(data);
|
|
} catch (err) { }
|
|
},
|
|
// 获取商品列表
|
|
async getGoodsList() {
|
|
if (this.loading || this.finished) {
|
|
return;
|
|
}
|
|
this.loadTitle = "";
|
|
this.loading = true;
|
|
|
|
try {
|
|
const { data } = await getGoodsList({
|
|
cId: this.activeId,
|
|
page: this.page++,
|
|
limit: this.limit,
|
|
});
|
|
|
|
this.goodsList = this.goodsList.concat(data);
|
|
this.finished = data.length < this.limit;
|
|
this.loadTitle = this.finished ? "已全部加载完" : "上拉加载更多";
|
|
} catch (err) { }
|
|
|
|
this.loading = false;
|
|
},
|
|
// 点击商品分类
|
|
handleCateClick(e) {
|
|
if (e.target.dataset.idx === undefined || this.loading) return;
|
|
|
|
this.clickedIndex = e.target.dataset.idx;
|
|
|
|
this.goodsList = [];
|
|
this.page = 1;
|
|
this.finished = false;
|
|
this.activeId = this.categoryList[this.clickedIndex].id;
|
|
this.getGoodsList();
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style>
|
|
page{
|
|
background: #F7F8F9;
|
|
}
|
|
</style>
|
|
<style lang="scss" scoped>
|
|
.goods-section{
|
|
width: 686rpx;
|
|
background: #FFFFFF;
|
|
border-radius: 24rpx;
|
|
margin: auto;
|
|
}
|
|
swiper {
|
|
|
|
/deep/ {
|
|
.wx-swiper-dots-horizontal,
|
|
.uni-swiper-dots-horizontal {
|
|
left: 70%;
|
|
}
|
|
|
|
.wx-swiper-dot,
|
|
.uni-swiper-dot {
|
|
width: 12rpx;
|
|
height: 8rpx;
|
|
background: #8ab1ff;
|
|
border-radius: 4rpx;
|
|
float: left;
|
|
}
|
|
|
|
.wx-swiper-dot-active,
|
|
.uni-swiper-dot-active {
|
|
width: 24rpx;
|
|
height: 8rpx;
|
|
background: #FFFFFF !important;
|
|
border-radius: 4rpx;
|
|
}
|
|
}
|
|
}
|
|
.nothing {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 400rpx;
|
|
height: 400rpx;
|
|
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
.swiper-box {
|
|
|
|
/* #ifndef MP-TOUTIAO */
|
|
padding-top: var(--safe-top);
|
|
height: 306rpx;
|
|
/* #endif */
|
|
|
|
}
|
|
|
|
.custom-banner {
|
|
width: 710rpx;
|
|
height: 370rpx;
|
|
border-radius: 20rpx;
|
|
margin: 0 auto;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.swiper-item {
|
|
padding: 30rpx 0;
|
|
}
|
|
|
|
.swiper-item image {
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 32rpx;
|
|
}
|
|
|
|
swiper {
|
|
|
|
/deep/ {
|
|
.wx-swiper-dots-horizontal,
|
|
.uni-swiper-dots-horizontal {
|
|
bottom: 60rpx;
|
|
}
|
|
|
|
.wx-swiper-dot,
|
|
.uni-swiper-dot {
|
|
width: 10rpx;
|
|
height: 10rpx;
|
|
border-radius: 5rpx;
|
|
margin-right: 5rpx;
|
|
margin-left: 5rpx;
|
|
}
|
|
|
|
.wx-swiper-dot-active,
|
|
.uni-swiper-dot-active {
|
|
width: 20rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.tab-box {
|
|
z-index: 1;
|
|
// background: #ffffff;
|
|
|
|
&.fixed {
|
|
top: 0;
|
|
padding-top: var(--safe-top);
|
|
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.03);
|
|
background-color: #FFFFFF;
|
|
}
|
|
}
|
|
|
|
.tab-content {
|
|
white-space: nowrap;
|
|
padding: 0 16rpx;
|
|
// background-color: #ffffff;
|
|
}
|
|
|
|
/deep/ ::-webkit-scrollbar {
|
|
display: none;
|
|
width: 0 !important;
|
|
height: 0 !important;
|
|
-webkit-appearance: none;
|
|
background: transparent;
|
|
}
|
|
|
|
.tab-item {
|
|
width: auto;
|
|
height: 92rpx;
|
|
padding: 0 25rpx;
|
|
font-size: 32rpx;
|
|
font-weight: 400;
|
|
color: #7A808A;
|
|
line-height: 92rpx;
|
|
|
|
&.on {
|
|
font-weight: bold;
|
|
font-size: 32rpx;
|
|
color: #23272E;
|
|
position: relative;
|
|
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
bottom: 20rpx;
|
|
left: 50%;
|
|
width: 32rpx;
|
|
height: 8rpx;
|
|
background: #1D8DFF;
|
|
border-radius: 4rpx;
|
|
transform: translateX(-50%);
|
|
}
|
|
}
|
|
}
|
|
|
|
.tab-bar-placeholder {
|
|
height: 92rpx;
|
|
/* #ifndef MP-TOUTIAO */
|
|
margin-top: calc(60rpx + var(--safe-top));
|
|
/* #endif */
|
|
}
|
|
/* #ifdef MP-KUAISHOU */
|
|
.swiper-item{
|
|
padding: 0 !important;
|
|
}
|
|
/* #endif */
|
|
.store{
|
|
padding-bottom: calc(var(--tab-bar-height) + 60rpx)
|
|
}
|
|
/* 商品列表 */
|
|
.store .finished,
|
|
.store .loading {
|
|
font-size: 28rpx;
|
|
line-height: 100rpx;
|
|
text-align: center;
|
|
color: #bbb;
|
|
}
|
|
|
|
.store .fa-spin {
|
|
|
|
animation: fa-spin 1s infinite linear;
|
|
}
|
|
|
|
.store .empty {
|
|
margin-top: 100rpx;
|
|
font-size: 28rpx;
|
|
text-align: center;
|
|
color: #bbb;
|
|
}
|
|
|
|
.store .empty image {
|
|
display: block;
|
|
width: 414rpx;
|
|
height: 305rpx;
|
|
margin: 0 auto;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.store .banner {
|
|
position: relative;
|
|
padding-top: 30rpx;
|
|
padding-bottom: 30rpx;
|
|
}
|
|
|
|
.store .banner .swiper-container {
|
|
width: 710rpx;
|
|
height: 310rpx;
|
|
border-radius: 20rpx;
|
|
}
|
|
|
|
.store .banner image {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 20rpx;
|
|
|
|
object-fit: cover;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.store .nothing {
|
|
display: block;
|
|
width: 414rpx;
|
|
margin: 30rpx auto;
|
|
pointer-events: none;
|
|
-webkit-touch-callout: none;
|
|
}
|
|
|
|
.store .list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
padding-top: 30rpx;
|
|
padding-right: 20rpx;
|
|
padding-left: 20rpx;
|
|
}
|
|
|
|
.store .list .item {
|
|
width: 320rpx;
|
|
margin-bottom: 30rpx;
|
|
padding: 0 8rpx;
|
|
}
|
|
|
|
.store .list .image {
|
|
height: 300rpx;
|
|
border-radius: 30rpx;
|
|
overflow: hidden;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.store .list .image .img {
|
|
width: 75%;
|
|
height: 75%;
|
|
border-radius: 12rpx;
|
|
object-fit: scale-down;
|
|
pointer-events: none;
|
|
-webkit-touch-callout: none;
|
|
}
|
|
|
|
.store .list .text {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
height: 148rpx;
|
|
padding-top: 13rpx;
|
|
}
|
|
|
|
.store .list .title {
|
|
overflow: hidden;
|
|
font-size: 28rpx;
|
|
line-height: 40rpx;
|
|
font-weight: 600;
|
|
color: #23272E;
|
|
-webkit-line-clamp: 2;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.store .list .group {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 0 6rpx;
|
|
}
|
|
|
|
.store .list .price {
|
|
font-size: 32rpx;
|
|
color: #23272E;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.store .list .price .num {
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
.store .list .sale {
|
|
font-size: 22rpx;
|
|
color: #aaa;
|
|
}
|
|
</style> |