JewelryMall/miniprogram/components/ProductCard.vue
2026-02-25 01:21:16 +08:00

85 lines
1.8 KiB
Vue

<template>
<view class="product-card" @click="goDetail">
<image class="product-card__image" :src="imgSrc()" mode="aspectFill" />
<view class="product-card__info">
<text class="product-card__name">{{ product.name }}({{ product.styleNo }})</text>
<view class="product-card__bottom">
<view class="product-card__price-tag">
<text class="product-card__price">¥{{ product.basePrice }}</text>
</view>
<text class="product-card__stock">库存{{ product.stock }}</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import type { Product } from '../types'
import { BASE_URL } from '../utils/request'
const props = defineProps<{ product : Product }>()
function imgSrc() : string {
const url = props.product.thumb || props.product.bannerImages?.[0]
if (!url) return '/static/logo.png'
if (url.startsWith('http')) return url
return BASE_URL + url
}
function goDetail() {
uni.navigateTo({ url: `/pages/product/detail?id=${props.product.id}` })
}
</script>
<style scoped>
.product-card {
display: flex;
flex-direction: column;
background: #fff;
border-radius: 16rpx;
overflow: hidden;
width: 100%;
}
.product-card__image {
width: 100%;
height: 340rpx;
}
.product-card__info {
padding: 16rpx 20rpx 20rpx;
}
.product-card__name {
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
line-height: 1.5;
}
.product-card__bottom {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12rpx;
}
.product-card__price-tag {
background: linear-gradient(135deg, #f5a0b8, #FF6D9B);
border-radius: 8rpx;
padding: 4rpx 16rpx;
}
.product-card__price {
font-size: 28rpx;
color: #fff;
font-weight: bold;
}
.product-card__stock {
font-size: 22rpx;
color: #999;
}
</style>