gy-app-shop/pages/tabBar/product.vue

243 lines
5.5 KiB
Vue

<template>
<view class="container">
<view class="header-box">
<!-- 搜索框 -->
<view class="search-box">
<u-search
v-model="searchValue"
placeholder="搜索商品"
:show-action="false"
@custom="onSearchFn"
@search="onSearchFn"
></u-search>
</view>
<!-- 分类标签 -->
<u-tabs
:list="tabList"
:current="tabCurrent"
name="dictLabel"
@change="tabChange"
:is-scroll="false"
item-style="padding-left: 15px; padding-right: 15px; height: 34px;"
></u-tabs>
</view>
<!-- 商品列表 -->
<mescroll-body
ref="mescrollRef"
top="186rpx"
@init="mescrollInit"
@down="downCallback"
@up="upCallback"
:up="upOption"
>
<view class="product-grid">
<view
class="product-item"
v-for="(item, index) in productList"
:key="item.id"
@click="goDetail(item)"
>
<image
:src="item.imageUrl"
mode="aspectFill"
class="product-image"
></image>
<view class="product-info">
<text class="product-name u-line-2">{{ item.name }}</text>
<view class="price-box">
<text class="current-price">¥{{ (item.price / 100).toFixed(2) }}</text>
<text class="original-price">¥{{ (item.listPrice / 100).toFixed(2) }}</text>
</view>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
export default {
data() {
return {
upOption:{
page:{
num : 0 ,
size : 12 ,
time : null
},
noMoreSize: 4,
empty:{
use : true ,
tip: '~ 商品列表为空 ~',
fixed: true,
top: "200rpx",
},
bgColor:"#f5f5f5"
},
searchValue: '',
tabCurrent: 0,
tabList: [], // 存储转换后的tab列表
productList: [],
mescroll: null,
pageNum: 1,
pageSize: 10,
currentCategory: '' // 当前选中的分类code
}
},
mixins:[MescrollMixin],
onLoad() {
this.getDictDataList('mall_product_category');
},
methods: {
// 获取分类列表
getDictDataList(type){
this.$api.getDictList(type).then((res)=>{
if(res.code===200){
this[type] = res.data || [];
if(type == 'mall_product_category'){
this.tabList = [{ dictLabel: '全部',dictValue: '' },...res.data]
}
}
})
},
// 上拉加载
upCallback(page) {
// this.getProductList(mescroll)
let pageNum = page.num; // 页码, 默认从1开始
let pageSize = page.size; // 页长, 默认每页10条
let obj = {
pageNum:pageNum,
pageSize:pageSize,
publishStatus:1,
name:this.searchValue,
categoryId:this.currentCategory,
orderByColumn: 'createTime',
isAsc: 'desc',
}
this.$api.productApi.getProductList(obj).then((res)=>{
console.log("当前商品列表",res)
if (res.rows && res.rows.length>0) {
// 接口返回的当前页数据列表 (数组)
let curPageData = res.rows;
// 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
let curPageLen = curPageData && curPageData.length;
//设置列表数据
console.log(curPageLen,res.total);
if(pageNum == 1){
this.productList = []; //如果是第一页需手动置空列表
// this.getUnreadNewIdList(); //
// this.getUnreadNewNum();
}
this.productList = this.productList.concat(curPageData); //追加新数据
this.mescroll.endBySize(curPageLen, res.total); // 推荐
this.loading = false;
} else{
this.productList = [];
this.mescroll.endErr();
this.mescroll.showEmpty();
this.loading = false;
// this.mescroll.endUpScroll(true)
}
}).catch(()=>{
this.$u.toast('服务器开小差了呢,请您稍后再试')
this.productList = [];
//联网失败, 结束加载
this.mescroll.endErr();
this.mescroll.showEmpty();
this.loading = false;
})
},
// 上拉加载
onSearchFn(){
this.mescroll.resetUpScroll();
},
// 切换分类
tabChange(index) {
this.tabCurrent = index
this.currentCategory = this.tabList[index].dictValue;
this.mescroll.resetUpScroll()
},
// 跳转到商品详情
goDetail(item) {
uni.navigateTo({
url: `/pages/product/detail?id=${item.id}`
})
}
}
}
</script>
<style lang="scss" scoped>
.container {
min-height: 100vh;
background-color: #f5f5f5;
.header-box{
position: fixed;
left: 0;
top: var(--window-top);
width: 100%;
z-index: 999;
background-color: #fff;
}
.search-box {
padding: 20rpx;
background-color: #fff;
}
}
.product-grid {
padding: 20rpx;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.product-item {
background-color: #fff;
border-radius: 12rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.product-image {
width: 100%;
height: 345rpx;
background-color: #f8f8f8;
}
.product-info {
padding: 16rpx;
}
.product-name {
font-size: 28rpx;
color: #333;
line-height: 1.4;
margin-bottom: 12rpx;
height: 80rpx;
}
.price-box {
display: flex;
align-items: baseline;
.current-price {
font-size: 32rpx;
color: #ff5500;
font-weight: bold;
margin-right: 12rpx;
}
.original-price {
font-size: 24rpx;
color: #999;
text-decoration: line-through;
}
}
}
</style>