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.
 
 
 
 
high-mini/pages/classify/goods-list/goods-list.vue

738 lines
17 KiB

<template>
<view style="height: 100%;">
<!-- <scroll-view :scroll-y="true" class="ht-auto goods-list" :scroll-top="scroll_top" @scroll="scroll_event" @scrolltolower="scroll_lower" @scrolltoupper="scroll_upper" lower-threshold="30"> -->
<!-- <data-list v-if="typeList=='classify'" :showEmpty="propData.length == 0" :page="pageData.pageStart" :size="pageData.pageNum" :selectObject="selectObject" class="ht-auto goods-list" ref="list" @load="handleLoad" @refresherrefresh="refresherrefresh"> -->
<scroll-view
v-if="typeList=='classify'"
class="scroll-view goods-list"
:scroll-top="scrollTop"
:scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="handleScrolltolower"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<view class="scroll-content1" :style="[scrollContentStyle]">
<!-- 下拉 -->
<view class="pull-down-view">
<view class="refresh-view" >
<text :class="' pull-down-text icon-ymt '+(refreshStatus == 'soon'?' to-blod-down ':refreshStatus == 'sure'?' to-blod-up ':' ') " >{{ refreshText[refreshStatus] }}</text>
</view>
</view>
<view class="scroll-list">
<view class="right-content-actual pr bs" :style="'padding-bottom:'+paddBottom+'px;'">
<view v-if="(propData || null) != null && propData.length > 0" class="oh">
<view v-for="(item, index) in propData" :key="index" >
<view @click="goGoodsDetail(item.id)" class="goods-item bs">
<image :src="imageUrl+item.listImg" mode="widthFix" class="goods-img"></image>
<view class="goods-detail">
<view class="goods-title">
<view class="goods-text">{{item.name}}</view>
<!-- <view v-if="(item.simple_desc || null) != null" class="goods-desc">{{item.simple_desc}}</view> -->
<view class="goods-desc">{{item.listDescribe || ''}}</view>
</view>
<view class="goods-item-bottom">
<view class="goods-price">
<view class="new-price">&yen;{{item.price}}</view>
<view class="old-price">&yen;{{item.originalPrice}}</view>
</view>
<view class="goods-num">
<view class="icon cart cart-class" @click.stop="cartIconChoose(item.id)">
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 空 -->
<view class=" empty-content" v-if="propData.length == 0">
<text class="empty-text">{{ emptyText }}</text>
</view>
<!-- 底部上滑 -->
<view class="pull-up-view" >
<view class="load-view" >
<view class="loading-animation" v-if="loadStatus == 'loading'"></view>
<text :class="' loading-text icon-ymt '+(loadStatus == 'soon'?' to-blod-up ':loadStatus == 'sure'?' to-blod-down ':' ') " >{{ loadText[loadStatus] }}</text>
</view>
</view>
</view>
</scroll-view>
<!--search-List -->
<scroll-view v-if="typeList=='goodsSearch'" :scroll-y="true" class="ht-auto goods-list" @scrolltolower="scroll_lower" lower-threshold="30">
<view class="right-content-actual pr bs" :style="'padding-bottom:'+paddBottom+'px;height:100%'">
<view v-if="(propData || null) != null && propData.length > 0" class="oh">
<view v-for="(item, index) in propData" :key="index" >
<view @click="goGoodsDetail(item.id)" class="goods-item bs">
<image :src="imageUrl+item.listImg" mode="widthFix" class="goods-img"></image>
<view class="goods-detail">
<view class="goods-title">
<view class="goods-text">{{item.name}}</view>
<!-- <view v-if="(item.simple_desc || null) != null" class="goods-desc">{{item.simple_desc}}</view> -->
<view class="goods-desc">{{item.listDescribe || ''}}</view>
</view>
<view class="goods-item-bottom">
<view class="goods-price">
<view class="new-price">&yen;{{item.price}}</view>
<view class="old-price">&yen;{{item.originalPrice}}</view>
</view>
<view class="goods-num">
<view class="icon cart cart-class" @click.stop="cartIconChoose(item.id)">
</view>
</view>
</view>
</view>
</view>
</view>
<noMore></noMore>
</view>
<!-- 空 -->
<view class=" empty-content" v-else>
<text class="empty-text">{{ emptyText }}</text>
</view>
</view>
</scroll-view>
<!-- 购物车 -->
<view class="gouwuche " @click="goCart">
<!-- cartNum -->
<uniBadge class="uni-badge-left-margin badgeClass" max-num="99" :text="cartNum+''" type="warning" size="small" />
<view class="icon cart font24px">
</view>
</view>
<!-- 选择类别 -->
<wybPopup ref="popup" type="bottom" width="500" scrollY="true" radius="6" :showCloseIcon="true">
<cart-choose @refreshCartNum="refreshCartNum" :specificationList="specificationList" @close="close"></cart-choose>
</wybPopup>
</view>
</template>
<script>
import noMore from '@/pages/classify/no-more/no-more.vue'
import wybPopup from '@/components/wyb-popup/wyb-popup.vue'
import cartChoose from '@/pages/classify/cart-choose/cart-choose.vue'
import { findGoodsSkuByGoodsId,getShoppingCartList } from '@/Utils/physicalObject.js'
import uniBadge from '@/components/uni-badge/components/uni-badge/uni-badge.vue'
const app = getApp();
export default {
data(){
return{
cartNum:0,
imageUrl: app.globalData.imgUrl,//图片地址
// start
refresherThreshold:50,
lowerThreshold:50,
pullingDown: false, // 是否正在下拉
pullDownHeight: 0, // 下拉高度
pullDownTimeStamp: 0, // 下拉时的时间戳
pullingUp: false, // 是否正在上拉
pullUpHeight: 0, // 上拉高度
pullUpTimeStamp: 0, // 上拉时的时间戳
maxDistance:100,
touchDirection:'top',
list:[],
emptyText:"暂无数据",
loadStatus: 'soon',
loadText: {
loading: '加载中~',
nomore: '没有更多啦~',
soon: '上滑查看下一分类',
sure: '释放查看下一分类',
},
refreshStatus: 'soon',
refreshText: {
soon: '下滑查看上一分类',
sure: '释放查看上一分类',
nomore: '没有更多啦~',
refreshing: '正在刷新中~'
},
//end
specificationList:[],
}
},
created(){
this.refreshCartNum();
},
props: {
propData: {
type: Array,
default: null
},
paddBottom:{
type:Number,
default:0,
},
pageData:{
type:Object,
default:{
pageStart:1,
pageNum:0,
allData:0
}
},
selectObject:{
type:Object,
default:{
selectIndex:0,
length:0
}
},
typeList:{
type:String,
default:"classify"
}
},
watch:{
selectObject:{
handler(n, o) {
if(n.selectIndex == n.length-1){
this.loadStatus = "nomore"
}else{
this.loadStatus = "soon"
}
if(n.selectIndex == 0){
this.refreshStatus = "nomore"
}else{
this.refreshStatus = "soon"
}
},
deep:true, // 深度监听
immediate:false, // 初始化监听
},
},
computed: {
scrollContentStyle() {
const style = {};
const { pullDownHeight, pullingDown,pullUpHeight, pullingUp } = this;
style.transform = pullingDown ? `translateY(${pullDownHeight}px)` : `translateY(0px)`;
style.transition = pullingDown ? `transform .1s linear` : `transform 0.3s cubic-bezier(0.19,1.64,0.42,0.72)`;
return style;
},
},
components:{
wybPopup,
cartChoose,
noMore,
uniBadge
},
methods:{
goCart(){
uni.navigateTo({
url:"/pages/classify/cart/cart"
})
},
// 刷新购物车数量
refreshCartNum(){
getShoppingCartList().then( res=>{
if (res.return_code == '000000') {
this.cartNum = res.return_data.length;
}else{
uni.showToast({
title: res.return_msg,
icon: 'none',
duration: 2000
})
}
})
},
//查看商品详情
goGoodsDetail(id) {
uni.navigateTo({
url: '../../classify/goodsDetail/goodsDetail?goodsId=' + id
})
},
// 购物车商品图标点击
cartIconChoose(id){
this.specificationList = [];
let params={
goodsId:id
};
console.log(params)
findGoodsSkuByGoodsId(params).then(res=>{
if (res.return_code == '000000') {
if(res.return_data&&res.return_data.length>0){
this.specificationList = res.return_data;
this.$refs.popup.show();
}else{
this.specificationList = [];
}
}else{
uni.showToast({
title: res.return_msg,
icon: 'none',
duration: 2000
})
}
})
},
//popup关闭选择方法
close(){
this.$refs.popup.hide();
},
scroll_lower(){
this.$emit("loadData")
},
//start
// 下滑触底后 数据加载
loadData() {
this.waiting = true;
this.$emit('loadData',res => {
this.waiting = false;
this.list = res.list;
this.total = res.total;
this.currentPage++;
this.handleComputeData();
// this.computedHeight();
});
},
// 计算高度
// computedHeight() {
// },
// 计算数据
handleComputeData() {
const len = this.list.length;
const total = this.total;
// console.log(len,total)
if (len >= this.total) {
this.loadStatus = 'soon';
} else if (len < this.total) {
this.loadStatus = 'loading';
}
},
// 下滑触底事件
handleScrolltolower(e) {
this.$emit('scrolltolower', e);
if (this.loadStatus == 'nomore' || this.waiting) return;
this.loadData();
},
// 滚动事件
handleScroll(e) {
// this.currentScrollTop = e.detail.scrollTop;
// if (e.detail.scrollTop <= 20) {
// this.touchDirection = 'top';
// } else {
// this.touchDirection = 'bottom';
// }
// console.log(e.detail.scrollTop)
this.$emit('scroll', e);
},
// 触摸按下处理
handleTouchStart(e) {
this.pullingDown = true;
this.currentTouchStartY = e.touches[0].clientY;
},
// 触摸按下滑动处理
handleTouchMove(e) {
// 顶部下滑
if (e.touches[0].clientY >= this.currentTouchStartY){
this.touchDirection = 'top';
const currentTouchMoveY = e.touches[0].clientY;
let movingDistance = (currentTouchMoveY - this.currentTouchStartY) ;
if(this.selectObject.selectIndex == 0){
this.refreshStatus = 'nomore'
}
else if(movingDistance > this.refresherThreshold){
this.refreshStatus = 'sure';// 释放
}else{
this.refreshStatus = 'soon';// 划
}
let computeDistance = movingDistance;
if(computeDistance > this.maxDistance){
computeDistance = this.maxDistance;
}
this.pullDownHeight = computeDistance ;
}else{
// 底部上滑
this.touchDirection = 'bottom';
const currentTouchMoveY = e.touches[0].clientY;
let movingDistance = (this.currentTouchStartY - currentTouchMoveY ) ;
if(this.selectObject.selectIndex == this.selectObject.length-1){
this.loadStatus = 'nomore';
}else if (movingDistance >= this.lowerThreshold) {
this.loadStatus = 'sure';//释放
} else {
this.loadStatus = 'soon';//划
}
let computeDistance = movingDistance;
if(computeDistance > this.maxDistance){
computeDistance = this.maxDistance;
}
this.pullUpHeight = computeDistance;
}
},
// 触摸松开处理
handleTouchEnd(e) {
// 顶部下滑
if(this.touchDirection == 'top'){
if(this.pullDownHeight>=this.refresherThreshold&&this.selectObject.selectIndex > 0){
this.$emit("switchCategory","prev")
}
this.pullingDown = false;
this.pullDownHeight = 0;
// 底部上滑
}else if(this.touchDirection == 'bottom'){
if(this.pullUpHeight>=this.lowerThreshold&&this.selectObject.selectIndex < (this.selectObject.length-1)){
this.$emit("switchCategory","next")
}
this.pullingUp = false;
this.pullUpHeight = 0;
}
},
// 初始化
handleInit() {
this.currentPage = this.page;
this.currentSize = this.size;
// console.log()
// this.computedHeight();
},
// end
}
}
</script>
<style lang="scss" scoped>
// 购物车
.gouwuche {
position: absolute;
bottom: 10px;
right: 15px;
width: 25px;
height: 25px;
color: #3DA7E7 !important;
}
.badgeClass {
position: absolute;
top:-5px;
right: -10px;
}
.font24px{
font-size: 24px !important;
color: #F0AD4E;
}
//
.br {
border: 1px solid #ffffff ;
}
.bs {
box-sizing: border-box;
}
.goods-list .goods-item{
display: flex;
align-items: center;
width: 100%;
height: 240rpx;
/* margin-bottom: 20rpx; */
color: #333333;
padding: 0 20rpx 10rpx;
border-bottom: 1px solid #F6F6F6;
}
.goods-list{
background-color: #ffffff;
}
.goods-list .goods-img {
/* width: 190rpx; */
height: 160rpx !important;
width: 160rpx;
padding: 10rpx;
}
.goods-list .goods-detail {
width: calc(100% - 190rpx);
height: 100%;
}
.goods-title {
width: 100%;
padding: 0 10rpx 0 0;
height: 140rpx;
}
.goods-title .goods-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 50rpx;
line-height: 50rpx;
font-size: 30rpx;
padding: 20rpx 0 10rpx;
}
.goods-title .goods-desc {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 40rpx;
line-height: 40rpx;
font-size: 24rpx;
color: #999999;
}
.goods-item-bottom{
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.goods-item-bottom .goods-price{
font-family: Arial;
padding-left: 20rpx;
}
.goods-item-bottom .new-price{
color: #3DA7E7;
font-weight: bold;
}
.goods-item-bottom .old-price{
font-size: 24rpx;
color: #D6D6D6;
font-weight: bold;
text-decoration:line-through;
}
.goods-item-bottom .goods-num{
height: 80rpx;
}
.goods-item-bottom .cart-class{
width: 80rpx;
height: 80rpx;
line-height: 80rpx;
color: #3DA7E7;
text-align: center;
font-size: 40rpx;
}
/* gundong */
// 空
.empty-content {
height:calc(100% - 20px) ;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.empty-image {
width: 100%;
}
.empty-text {
display: block;
color: #606266;
margin-top: 20rpx;
}
}
.scroll-view {
height: 100%;
.scroll-content1{
width: 100%;
height: 100%;
position: relative;
.empty-view {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.pull-down-view {
top: 0;
left: 0;
width: 100%;
padding: 30rpx 0;
display: flex;
position: absolute;
align-items: center;
flex-direction: column;
justify-content: center;
transform: translateY(-100%);
.refresh-view {
display: flex;
align-items: center;
flex-direction: column;
.loading-animation {
width: 50rpx;
height: 50rpx;
}
.pull-down-text {
color: #606266;
font-size: 24rpx;
margin-top: 10rpx;
}
}
}
.scroll-list {
display: flex;
flex-direction: column;
}
.loading-view {
width: 100%;
height: 100%;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.loading-animation {
width: 40rpx;
height: 40rpx;
}
.loading-text {
color: #606266;
font-size: 24rpx;
margin-top: 10rpx;
}
}
.pull-up-view {
width: 100%;
// padding: 15rpx 0;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
.load-view {
display: flex;
align-items: center;
.loading-text {
color: #606266;
font-size: 24rpx;
margin-left: 20rpx;
}
}
}
.loading-animation {
position: relative;
&::after,
&::before {
left: 0;
width: 100%;
position: absolute;
border: 0 solid currentColor;
background-color: #b7b7b7;
}
&::after {
content: '';
top: -25%;
z-index: 1;
height: 100%;
border-radius: 10%;
animation: spin 0.6s -0.1s linear infinite;
}
&::before {
content: '';
bottom: -9%;
height: 10%;
background: #000;
border-radius: 50%;
opacity: 0.2;
animation: shadow 0.6s -0.1s linear infinite;
}
@keyframes spin {
17% {
border-bottom-right-radius: 10%;
}
25% {
transform: translateY(25%) rotate(22.5deg);
}
50% {
border-bottom-right-radius: 100%;
transform: translateY(50%) scale(1, 0.9) rotate(45deg);
}
75% {
transform: translateY(25%) rotate(67.5deg);
}
100% {
transform: translateY(0) rotate(90deg);
}
}
@keyframes shadow {
50% {
transform: scale(1.25, 1);
}
}
}
}
}
</style>