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/components/goods-list/goods-list.vue

799 lines
17 KiB

<template>
<view style="height: 100%;">
<!-- perspective: 1000; -->
<scroll-view v-if="typeList=='classify'" class="scroll-view goods-list" :scroll-top="scrollTop"
@scroll="handleScroll" scroll-y="true" :lower-threshold="lowerThreshold"
@scrolltolower="handleScrolltolower" @touchstart="handleTouchStart"
@touchmove.stop.prevent="handleTouchMove" @touchend="handleTouchEnd">
<!-- @touchmove.stop.prevent @touch.stop -->
<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="aspectFill" class="goods-img bs"></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">
<image class="empty-text" mode="widthFix" :src="imagewxUrl+imgadres"></image>
<!-- <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" @scroll="handleScroll"
:scroll-top="scrollTop" @scrolltolower="scroll_lower" lower-threshold="30">
<!-- <view class="right-content-actual pr bs" :style="'padding-bottom:'+paddBottom+'px;'"> -->
<view v-if="(propData || null) != null && propData.length > 0">
<view v-for="(item, index) in propData" :key="index">
<view @click="goGoodsDetail(item.id)" class="goods-item bs">
<image :src="imageUrl+item.listImg" mode="aspectFill" class="goods-img bs"></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 :bgColor="'#ffffff'"></noMore>
</view>
<!-- 空 -->
<view class=" empty-content" v-else>
<image class="empty-text" mode="widthFix" :src="imagewxUrl+imgadres"></image>
<!-- <text class="empty-text">{{ emptyText }}</text> -->
</view>
<!-- </view> -->
</scroll-view>
<!-- 购物车 -->
<view :class="' gouwuche searchCart ' " @click.prevent="goCart">
<!-- cartNum -->
<uniBadge class="uni-badge-left-margin badgeClass" max-num="99" :text="cartNum+''" type="warning"
size="small" />
<view class="icon cart font40">
</view>
</view>
<!-- 选择类别 -->
<wybPopup ref="popup" zIndex="999" type="bottom" height="500" 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 '@/components/no-more/no-more.vue'
import wybPopup from '@/components/wyb-popup/wyb-popup.vue'
import cartChoose from '@/components/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, //图片地址
imagewxUrl: app.globalData.imageWxImg,
imgadres: 'goods_default_pages.png',
scrollTop: 0,
currentScrollTop: 0,
// start
refresherThreshold: 50,
lowerThreshold: 50,
pullingDown: false, // 是否正在下拉
pullDownHeight: 0, // 下拉高度
pullDownTimeStamp: 0, // 下拉时的时间戳
pullingUp: false, // 是否正在上拉
pullUpHeight: 0, // 上拉高度
pullUpTimeStamp: 0, // 上拉时的时间戳
maxDistance: 100,
touchDirection: '',
list: [],
emptyText: "暂无数据",
loadStatus: 'soon',
loadText: {
loading: '加载中~',
nomore: '',
soon: '上滑查看下一分类',
sure: '释放查看下一分类',
},
refreshStatus: 'soon',
refreshText: {
soon: '下滑查看上一分类',
sure: '释放查看上一分类',
nomore: '没有更多啦~',
refreshing: '正在刷新中~'
},
//end
specificationList: [],
}
},
created() {
this.refreshCartNum();
},
mounted() {
this.handleInit();
},
props: {
propData: {
type: Array,
default () {
return []
}
},
paddBottom: {
type: Number,
default: 0,
},
pageData: {
type: Object,
default() {
return {
pageStart: 1,
pageNum: 0,
allData: 0
}
}
},
selectObject: {
type: Object,
default(){
return {
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: true, // 初始化监听
},
},
computed: {
scrollContentStyle() {
const style = {};
const {
pullDownHeight,
pullingDown,
pullUpHeight,
pullingUp
} = this;
style.transform = pullingDown && !pullingUp ? `translateY(${pullDownHeight}px)` : `translateY(0px)`;
style.transition = pullingDown && !pullingUp ? `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: "/physical-merchants/classify/cart/cart"
})
},
// 刷新购物车数量
refreshCartNum() {
this.scrollTop = this.currentScrollTop;
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: '/physical-merchants/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();
// console.log(this.specificationList)
} 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();
});
},
// 计算数据
handleComputeData() {
const len = this.list.length;
const total = this.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;
// 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.pullingUp = false;
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.pullingUp = true;
this.pullingDown = false;
// 底部上滑
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")
}
// 底部上滑
} else if (this.touchDirection == 'bottom') {
if (this.pullUpHeight >= this.lowerThreshold && this.selectObject.selectIndex < (this.selectObject
.length - 1)) {
this.$emit("switchCategory", "next")
}
}
this.pullDownHeight = 0;
this.pullUpHeight = 0;
this.pullingDown = false;
this.pullingUp = false;
},
// 初始化
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: 25px;
width: 35px;
height: 35px;
color: #3DA7E7 !important;
.font40 {
font-size: 35px !important;
color: #F0AD4E;
}
}
.searchCart {
bottom: 27px !important;
right: 30px !important;
}
.badgeClass {
position: absolute;
top: -5px;
right: -10px;
}
//
.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: 100% !important;
width: 200rpx;
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;
font-size: 18px;
}
.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: 50rpx;
}
/* gundong */
// 空
.empty-content {
height: calc(100% - 20px);
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.empty-image {
width: 100%;
}
.empty-text {
width: 80%;
display: block;
color: #606266;
margin-top: 40rpx;
margin-bottom: 20rpx;
}
}
.scroll-view {
height: 100%;
.scroll-content1 {
width: 100%;
padding-bottom: 40px;
// position: relative;
// height: inherit;
.empty-view {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.pull-down-view {
width: 100%;
top: 0;
left: 0;
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>