ProductCard.vue
3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<template>
<view
class="relative bg-white rounded-[24rpx] p-[32rpx] border border-gray-200 product-card overflow-hidden transition-all duration-300 active:scale-[0.99]"
style="box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.05);"
>
<!-- 装饰背景: 右上角灰色光晕 -->
<view class="absolute -right-[40rpx] -top-[40rpx] w-[160rpx] h-[160rpx] bg-gray-100 rounded-full opacity-60 blur-[30rpx] pointer-events-none"></view>
<!-- 内容区域 -->
<view class="relative z-10">
<!-- 头部:标题与标签 -->
<view class="mb-[36rpx]">
<!-- 产品名称 -->
<text class="block text-gray-900 text-[34rpx] font-bold leading-[1.4] mb-[20rpx] tracking-tight">
{{ productName }}
</text>
<!-- 产品标签 -->
<view v-if="tags && tags.length" class="flex flex-wrap gap-[12rpx]">
<view
v-for="tag in tags"
:key="tag.id"
class="text-[22rpx] px-[16rpx] py-[6rpx] rounded-[8rpx] font-medium flex items-center justify-center transition-opacity"
:style="{
backgroundColor: tag.bg_color || '#F3F4F6',
color: tag.text_color || '#4B5563',
border: `1px solid ${tag.bg_color ? 'transparent' : '#E5E7EB'}`
}"
>
{{ tag.name }}
</view>
</view>
</view>
<!-- 操作按钮组 -->
<view class="flex justify-between gap-[20rpx]">
<!-- 详情按钮: 柔和的灰色背景 -->
<view
class="flex-1 h-[76rpx] flex items-center justify-center rounded-[16rpx] bg-[#F3F4F6] active:bg-[#E5E7EB] transition-colors"
@tap.stop="handleDetail"
>
<text class="text-[28rpx] text-gray-600 font-medium">产品详情</text>
</view>
<!-- 计划书按钮: 柔和的蓝色背景,降低对比度 -->
<view
class="flex-1 h-[76rpx] flex items-center justify-center rounded-[16rpx] bg-[#EFF6FF] active:bg-[#DBEAFE] transition-colors"
@tap.stop="handlePlan"
>
<text class="text-[28rpx] text-blue-600 font-medium">制作计划书</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
/**
* 产品卡片组件
*
* @description 热卖产品列表项卡片,展示产品名称、标签和操作按钮
* @component ProductCard
*/
import { defineProps, defineEmits } from 'vue';
/**
* 组件属性
*/
const props = defineProps({
/** 产品 ID */
productId: {
type: Number,
required: true
},
/** 产品名称 */
productName: {
type: String,
required: true
},
/** 产品标签数组 */
tags: {
type: Array,
default: () => []
}
});
/**
* 组件事件
*/
const emit = defineEmits({
/** 点击产品详情按钮 */
detail: (productId) => typeof productId === 'number',
/** 点击计划书按钮 */
plan: (productId) => typeof productId === 'number'
});
/**
* 处理产品详情点击
*
* @description 触发 detail 事件,传递产品 ID
*/
const handleDetail = () => {
emit('detail', props.productId);
};
/**
* 处理计划书点击
*
* @description 触发 plan 事件,传递产品 ID
*/
const handlePlan = () => {
emit('plan', props.productId);
};
</script>
<style lang="less" scoped>
.product-card {
// 保持 scoped 样式块,方便未来扩展
}
</style>