585 lines
11 KiB
Vue
585 lines
11 KiB
Vue
<template>
|
||
<view
|
||
:class="{ goods: true, 'goods-card': card, 'goods-list': list, 'goods-min': min, 'goods-fill': fill, 'goods-round': round }"
|
||
@tap="toDetail"
|
||
>
|
||
<view
|
||
class="goods-header"
|
||
>
|
||
<view class="goods-thumb">
|
||
<image
|
||
:src="data.image"
|
||
class="goods-thumb-img"
|
||
style="object-fit: cover"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view :class="['goods-content']">
|
||
<view
|
||
class="goods-storeName"
|
||
>{{ data.storeName }}
|
||
</view>
|
||
<view
|
||
class="goods-list-model"
|
||
v-if="selectModel"
|
||
>
|
||
<div
|
||
class="goods-list-model-border"
|
||
@tap.stop="handleOpenSelect"
|
||
>
|
||
<view class="goods-list-model-label">{{ data.attrInfo.sku }}</view>
|
||
<view class="goods-list-model-action icon">
|
||
<image src="@/static/images/down.png" />
|
||
</view>
|
||
</div>
|
||
</view>
|
||
<view
|
||
class="goods-list-model-info"
|
||
v-if="model"
|
||
>
|
||
<view class="goods-list-model-label">{{ data.attrInfo.sku }}</view>
|
||
|
||
<!-- <view class="goods-list-model-info-label">颜色:</view>
|
||
<view class="goods-list-model-info-value">黑色</view>
|
||
<view class="goods-list-model-info-label">尺码:</view>
|
||
<view class="goods-list-model-info-value">M</view> -->
|
||
</view>
|
||
<view class="goods-info">
|
||
<view class="goods-info-left">
|
||
<view
|
||
class="goods-desc"
|
||
v-if="groupNum"
|
||
>{{ data.groupNum }}人团
|
||
</view>
|
||
<view
|
||
class="goods-price-row"
|
||
v-if="primary"
|
||
>
|
||
<view class="goods-price goods-price-primary">
|
||
¥{{price || data.price }}
|
||
</view>
|
||
<view
|
||
class="goods-price goods-price-original"
|
||
v-if="original"
|
||
>
|
||
¥{{ data.original }}
|
||
</view>
|
||
</view>
|
||
<view
|
||
class="goods-price goods-price-default"
|
||
v-if="!primary"
|
||
>
|
||
<slot
|
||
name="price"
|
||
:row="data"
|
||
>
|
||
¥{{price || data.price }}
|
||
</slot>
|
||
</view>
|
||
</view>
|
||
<view class="goods-info-action">
|
||
<view class="goods-info-action-btn">
|
||
<slot name="action"></slot>
|
||
</view>
|
||
<view
|
||
v-if="stock"
|
||
class="goods-info-action-desc"
|
||
>
|
||
<text v-if="data.stock">仅剩{{ data.stock }}件</text>
|
||
<text v-else>库存不足</text>
|
||
</view>
|
||
|
||
<view
|
||
class="buy-num"
|
||
v-if="purchase"
|
||
>
|
||
<view class="buy-num-info-desc">
|
||
x{{ purchase }}
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-if="buyProgress">
|
||
<view class="buy-progress">
|
||
<view class="buy-progress-info">
|
||
<view
|
||
class="buy-progress-info-desc"
|
||
v-if="quantity"
|
||
>
|
||
限量{{ data.quantity }}件
|
||
</view>
|
||
<uv-line-progress
|
||
:percentage="50"
|
||
:showText="false"
|
||
/>
|
||
</view>
|
||
<view class="buy-progress-action">
|
||
<uv-button
|
||
round
|
||
block
|
||
type="primary"
|
||
>
|
||
立即抢购
|
||
</uv-button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<good-attr-select
|
||
ref="selectAttrPanel"
|
||
:id="data.id"
|
||
@select="handleSelectAttr"
|
||
/>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue'
|
||
import { useRouter } from "@/hooks/useRouter";
|
||
|
||
const props = defineProps(['data', 'min', 'groupNum', 'original', 'stock', 'primary', 'card', 'list', 'buyProgress', 'quantity', 'selectModel', 'model', 'purchase', 'link', 'fill', 'round','price'])
|
||
|
||
// 团购人数
|
||
const groupNum = ref(props.groupNum)
|
||
// 剩余数量
|
||
const stock = ref(props.stock)
|
||
// 使用主题颜色的价格
|
||
const primary = ref(props.primary !== undefined)
|
||
// 卡片模式
|
||
const card = ref(props.card !== undefined)
|
||
// 列表模式
|
||
const list = ref(props.list !== undefined)
|
||
// 限量多少件
|
||
const quantity = ref(props.quantity)
|
||
// 显示购买进度
|
||
const buyProgress = ref(props.buyProgress)
|
||
// 选择规格
|
||
const selectModel = ref(props.selectModel !== undefined)
|
||
// 显示规格
|
||
const model = ref(props.model !== undefined)
|
||
// 购买数量
|
||
const purchase = ref(props.purchase)
|
||
// 购买价格
|
||
const price = ref(props.price)
|
||
|
||
|
||
// 原价
|
||
const original = ref(props.original)
|
||
|
||
// 小尺寸
|
||
const min = ref(props.min)
|
||
const selectAttrPanel = ref(null)
|
||
const link = ref(props.link !== undefined)
|
||
const fill = ref(props.fill !== undefined)
|
||
const round = ref(props.round !== undefined)
|
||
const {push} = useRouter()
|
||
const toDetail = () => {
|
||
if (!link.value) {
|
||
return
|
||
}
|
||
push({url: '/pages/goodsDetail/goodsDetail'}, {data: {id: props.data.id}})
|
||
}
|
||
|
||
const handleOpenSelect = () => {
|
||
selectAttrPanel.value.open()
|
||
}
|
||
|
||
const handleSelectAttr = () => {
|
||
|
||
}
|
||
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.goods {
|
||
position: relative;
|
||
padding: 30rpx 0;
|
||
|
||
|
||
&-card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
.goods {
|
||
&-content {
|
||
padding: 0 20rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
&-info {
|
||
margin-top: 15rpx;
|
||
}
|
||
|
||
&-thumb {
|
||
margin-bottom: 15rpx;
|
||
width: 100%;
|
||
|
||
&-img {
|
||
width: 300rpx;
|
||
height: 300rpx;
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
&-header {
|
||
}
|
||
|
||
&-thumb {
|
||
background: #FAFAFA;
|
||
}
|
||
|
||
&-content {
|
||
}
|
||
|
||
&-storeName {
|
||
line-height: 40rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
}
|
||
|
||
|
||
&-price {
|
||
&-row {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.goods-price {
|
||
}
|
||
}
|
||
|
||
&-primary {
|
||
line-height: 42rpx;
|
||
font-size: 30rpx;
|
||
color: #EE6D46;
|
||
}
|
||
|
||
&-default {
|
||
line-height: 42rpx;
|
||
font-size: 30rpx;
|
||
color: #EE6D46;
|
||
}
|
||
|
||
&-original {
|
||
margin-left: 9rpx;
|
||
line-height: 28rpx;
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
text-decoration: line-through;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
&-desc {
|
||
line-height: 33rpx;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
&-info {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
justify-content: space-between;
|
||
|
||
&-left {
|
||
}
|
||
|
||
&-action {
|
||
&-btn {
|
||
}
|
||
|
||
&-desc {
|
||
line-height: 28rpx;
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
&-image {
|
||
&-img {
|
||
}
|
||
}
|
||
|
||
&-list {
|
||
display: flex;
|
||
flex-direction: row;
|
||
padding: 40rpx 34rpx 30rpx;
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
|
||
.goods {
|
||
&-thumb {
|
||
margin-bottom: 0;
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
|
||
&-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
&-content {
|
||
margin-left: 40rpx;
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
width: 0;
|
||
}
|
||
}
|
||
|
||
|
||
&-model {
|
||
display: flex;
|
||
|
||
|
||
margin-bottom: 28rpx;
|
||
|
||
&-border {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 40rpx;
|
||
border: 1px solid #CCCCCC;
|
||
opacity: 1;
|
||
border-radius: 0rpx;
|
||
padding: 0 10rpx;
|
||
}
|
||
|
||
&-info {
|
||
}
|
||
|
||
&-label {
|
||
line-height: 38rpx;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
&-value {
|
||
line-height: 38rpx;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
&-action {
|
||
width: 11rpx;
|
||
height: 7rpx;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
&-min {
|
||
.goods {
|
||
&-thumb {
|
||
margin-bottom: 0;
|
||
width: 150rpx;
|
||
height: 150rpx;
|
||
|
||
&-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
&-fill {
|
||
padding-top: 0;
|
||
}
|
||
|
||
&-round {
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
// .goods {
|
||
// padding: 16rpx 14rpx;
|
||
|
||
// &-header {
|
||
// display: flex;
|
||
// align-items: flex-start;
|
||
// }
|
||
|
||
// &-thumb {
|
||
|
||
// width: 220rpx;
|
||
// height: 220rpx;
|
||
|
||
// &-img {
|
||
// width: 100%;
|
||
// height: 100%;
|
||
// display: block;
|
||
// }
|
||
// }
|
||
|
||
// &-content {
|
||
// margin-top: 24rpx;
|
||
// margin-left: 40rpx;
|
||
// flex: 1
|
||
// }
|
||
|
||
// &-storeName {
|
||
// line-height: 40rpx;
|
||
// font-size: 28rpx;
|
||
// font-weight: 500;
|
||
// color: #333333;
|
||
// margin-bottom: 35rpx;
|
||
// }
|
||
|
||
// &-info {
|
||
// display: flex;
|
||
// align-items: center;
|
||
// justify-content: space-between;
|
||
|
||
// &-left {
|
||
// display: flex;
|
||
// align-items: flex-end;
|
||
|
||
// }
|
||
|
||
// &-action {
|
||
// &-btn {}
|
||
|
||
// &-desc {
|
||
// color: #999999;
|
||
// font-size: 24rpx;
|
||
// line-height: 40rpx;
|
||
// }
|
||
// }
|
||
|
||
// }
|
||
|
||
|
||
// &-price {
|
||
// &-default {
|
||
// line-height: 28rpx;
|
||
// font-size: 20rpx;
|
||
// color: #999999;
|
||
|
||
// }
|
||
|
||
// &-primary {
|
||
// line-height: 42rpx;
|
||
// font-size: 30rpx;
|
||
// font-weight: 500;
|
||
// color: #EE6D46;
|
||
// margin-left: 5rpx;
|
||
// }
|
||
// }
|
||
|
||
|
||
// &-desc {
|
||
// color: #999999;
|
||
// font-size: 24rpx;
|
||
// line-height: 40rpx;
|
||
// }
|
||
|
||
|
||
&-model {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
width: auto;
|
||
height: 40rpx;
|
||
border: 1px solid #CCCCCC;
|
||
opacity: 1;
|
||
border-radius: 0rpx;
|
||
padding: 0 10rpx;
|
||
|
||
margin-bottom: 28rpx;
|
||
|
||
&-label {
|
||
line-height: 38rpx;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
&-value {
|
||
line-height: 38rpx;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
&-action {
|
||
width: 11rpx;
|
||
height: 7rpx;
|
||
}
|
||
}
|
||
|
||
// &-model-info {
|
||
// display: inline-flex;
|
||
// align-items: center;
|
||
// width: auto;
|
||
// height: 40rpx;
|
||
// opacity: 1;
|
||
// border-radius: 0rpx;
|
||
// margin-bottom: 28rpx;
|
||
|
||
// &-label {
|
||
// line-height: 38rpx;
|
||
// font-size: 24rpx;
|
||
// color: #999999;
|
||
// }
|
||
|
||
// &-value {
|
||
// line-height: 38rpx;
|
||
// font-size: 24rpx;
|
||
// color: #333333;
|
||
// margin-right: 10rpx;
|
||
// }
|
||
|
||
// &-action {
|
||
// width: 11rpx;
|
||
// height: 7rpx;
|
||
// }
|
||
// }
|
||
// }
|
||
}
|
||
|
||
.buy-progress {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
&-info {
|
||
flex: 1;
|
||
|
||
&-desc {
|
||
color: #999999;
|
||
font-size: 24rpx;
|
||
line-height: 32rpx;
|
||
}
|
||
}
|
||
|
||
&-action {
|
||
margin-left: 17rpx;
|
||
}
|
||
}
|
||
|
||
.buy-num {
|
||
&-info-desc {
|
||
color: #999999;
|
||
font-size: 24rpx;
|
||
line-height: 32rpx;
|
||
}
|
||
}
|
||
</style>
|