'首页和商品详情页初稿'
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<!-- 颜色选择:第一行 4 个,第二行 2 个;胶囊样式,选中橙色边框+橙色文字 -->
|
||||
<view class="color-wrap">
|
||||
<text class="title">颜色</text>
|
||||
|
||||
<view class="color-list">
|
||||
<view
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
class="color-pill"
|
||||
:class="{ active: selectedId === item.id }"
|
||||
@tap="selectColor(item.id)"
|
||||
>
|
||||
<view class="color-dot" :style="{ background: item.value }"></view>
|
||||
<text class="color-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ColorSelector',
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
selectedId: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectColor(id) {
|
||||
this.$emit('select', id)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.color-wrap {
|
||||
padding: 30rpx 20rpx; /* 15px 10px */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 29rpx; /* 15px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
margin-bottom: 30rpx; /* 15px */
|
||||
}
|
||||
|
||||
/* 胶囊列表 */
|
||||
.color-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx; /* 8px 横向 / 纵向 */
|
||||
}
|
||||
|
||||
/* 单个胶囊:padding 5px 12px,圆角 60px */
|
||||
.color-pill {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx; /* 4px */
|
||||
padding: 10rpx 24rpx; /* 5px 12px */
|
||||
border: 1rpx solid #f2f2f2;
|
||||
border-radius: 120rpx; /* 60px */
|
||||
background: #ffffff;
|
||||
}
|
||||
.color-pill.active {
|
||||
border-color: #ff6800;
|
||||
}
|
||||
|
||||
/* 颜色圆点 15x15,1px 灰色边框 */
|
||||
.color-dot {
|
||||
width: 30rpx; /* 15px */
|
||||
height: 30rpx;
|
||||
border-radius: 50%;
|
||||
border: 1rpx solid #cdcdcd;
|
||||
}
|
||||
|
||||
/* 颜色名称 14px 黑,选中橙色 */
|
||||
.color-name {
|
||||
font-size: 27rpx; /* 14px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.color-pill.active .color-name {
|
||||
color: #ff6800;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<!-- 产品图片轮播 + 自定义指示点 -->
|
||||
<view class="detail-swiper">
|
||||
<swiper
|
||||
class="swiper"
|
||||
:circular="true"
|
||||
:indicator-dots="false"
|
||||
@change="onChange"
|
||||
>
|
||||
<swiper-item v-for="(item, index) in images" :key="index">
|
||||
<view class="swiper-item">
|
||||
<image class="swiper-image" :src="item" mode="aspectFill"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<!-- 自定义指示点:active 16x8 橙色胶囊,inactive 8x8 黑色 20% -->
|
||||
<view class="dots">
|
||||
<view
|
||||
v-for="(item, index) in images"
|
||||
:key="index"
|
||||
class="dot"
|
||||
:class="{ active: current === index }"
|
||||
></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DetailSwiper',
|
||||
props: {
|
||||
images: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
this.current = e.detail.current
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.detail-swiper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 500rpx; /* 260px */
|
||||
}
|
||||
.swiper-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.swiper-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 指示点:覆盖在图片底部 */
|
||||
.dots {
|
||||
position: absolute;
|
||||
bottom: 20rpx; /* 距图片底部 10px */
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx; /* 6px */
|
||||
}
|
||||
.dot {
|
||||
width: 16rpx; /* 8px */
|
||||
height: 16rpx;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 8rpx; /* 4px */
|
||||
}
|
||||
.dot.active {
|
||||
width: 32rpx; /* 16px */
|
||||
height: 16rpx; /* 8px */
|
||||
background: #ff6800;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<!-- 包装规格表:4 列 × 4 行,每个数据单元格双单位(cm + in) -->
|
||||
<view class="pack-wrap">
|
||||
<view class="header-row">
|
||||
<text class="title">包装规格</text>
|
||||
<text class="unit">单位:{{ data.unit }}</text>
|
||||
</view>
|
||||
|
||||
<view class="table">
|
||||
<!-- 表头:bg #DFDFDF,圆角 6px -->
|
||||
<view class="row header">
|
||||
<text
|
||||
class="cell"
|
||||
v-for="(col, index) in data.columns"
|
||||
:key="index"
|
||||
>{{ col }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 数据行:偶数行 bg #F7F7F7,行高 60px(双行内容) -->
|
||||
<view
|
||||
class="row data-row"
|
||||
:class="{ alt: (index + 1) % 2 === 0 }"
|
||||
v-for="(row, index) in data.rows"
|
||||
:key="index"
|
||||
>
|
||||
<!-- 尺码列:单行居中 -->
|
||||
<view class="cell size-cell">
|
||||
<text class="size-text">{{ row.size }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 尺寸列:cm + in 双行 -->
|
||||
<view class="cell dual-cell">
|
||||
<text class="dual-top">{{ row.dimension.cm }}</text>
|
||||
<text class="dual-bottom">{{ row.dimension.in }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 体积列:cm + in 双行 -->
|
||||
<view class="cell dual-cell">
|
||||
<text class="dual-top">{{ row.volume.cm }}</text>
|
||||
<text class="dual-bottom">{{ row.volume.in }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 重量列:cm + in 双行 -->
|
||||
<view class="cell dual-cell">
|
||||
<text class="dual-top">{{ row.weight.cm }}</text>
|
||||
<text class="dual-bottom">{{ row.weight.in }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PackagingSpec',
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pack-wrap {
|
||||
padding: 30rpx 20rpx; /* 15px 10px */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 标题行 */
|
||||
.header-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx; /* 10px */
|
||||
}
|
||||
.title {
|
||||
font-size: 29rpx; /* 15px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.unit {
|
||||
margin-left: 16rpx;
|
||||
font-size: 21rpx; /* 11px */
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* 表格 */
|
||||
.table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx; /* 4px 行间距 */
|
||||
}
|
||||
|
||||
/* 单行 */
|
||||
.row {
|
||||
display: flex;
|
||||
border-radius: 12rpx; /* 6px */
|
||||
align-items: center;
|
||||
}
|
||||
.row.header {
|
||||
height: 77rpx; /* 40px */
|
||||
background: #dfdfdf;
|
||||
}
|
||||
.row.data-row {
|
||||
height: 115rpx; /* 60px 双行内容更高 */
|
||||
}
|
||||
.row.alt {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
/* 单元格 */
|
||||
.cell {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 表头文字 */
|
||||
.row.header .cell {
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* 尺码列:单行 13px */
|
||||
.size-text {
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* 双单位单元格:cm 在上,in 在下 */
|
||||
.dual-cell {
|
||||
gap: 4rpx; /* 2px */
|
||||
}
|
||||
.dual-top,
|
||||
.dual-bottom {
|
||||
font-size: 19rpx; /* 10px */
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
line-height: 33rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<!-- 产品参数:普通参数行 + 可展开的"补充说明" -->
|
||||
<view class="params-wrap">
|
||||
<text class="title">产品参数</text>
|
||||
|
||||
<!-- 普通参数行 -->
|
||||
<view
|
||||
class="param-row"
|
||||
v-for="(item, index) in normalParams"
|
||||
:key="index"
|
||||
>
|
||||
<text class="param-label">{{ item.label }}</text>
|
||||
<text class="param-value">{{ item.value }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 可展开的"补充说明" -->
|
||||
<view class="param-row expandable-row" v-if="expandableParam">
|
||||
<text class="param-label">{{ expandableParam.label }}</text>
|
||||
<view class="expandable-content">
|
||||
<text class="param-value" :class="{ 'value-collapsed': !expanded }">{{ expandableParam.value }}</text>
|
||||
|
||||
<!-- 渐变遮罩 + 展开按钮(仅收起态显示) -->
|
||||
<view class="expand-overlay" v-if="!expanded">
|
||||
<view class="gradient-mask"></view>
|
||||
<view class="expand-btn" @tap="toggleExpand">
|
||||
<text class="expand-text">展开</text>
|
||||
<view class="arrow-down"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 展开后的"收起"按钮 -->
|
||||
<view class="collapse-btn" v-if="expanded" @tap="toggleExpand">
|
||||
<text class="expand-text">收起</text>
|
||||
<view class="arrow-up"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ParamsTable',
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
expanded: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
normalParams() {
|
||||
return this.list.filter((item) => !item.expandable)
|
||||
},
|
||||
expandableParam() {
|
||||
return this.list.find((item) => item.expandable)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleExpand() {
|
||||
this.expanded = !this.expanded
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.params-wrap {
|
||||
padding: 30rpx 20rpx; /* 15px 10px */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 29rpx; /* 15px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
margin-bottom: 20rpx; /* 10px */
|
||||
}
|
||||
|
||||
/* 普通参数行 */
|
||||
.param-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 10rpx 0; /* 5px 上下 */
|
||||
}
|
||||
.param-label {
|
||||
width: 170rpx; /* 给 label 固定宽度对齐 */
|
||||
flex-shrink: 0;
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: rgba(0, 0, 0, 0.5); /* 黑色 50% 透明度 */
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.param-value {
|
||||
flex: 1;
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* 可展开的"补充说明"行 */
|
||||
.expandable-row {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.expandable-content {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 收起态:限制高度(约 5 行,留出渐变遮罩空间) */
|
||||
.value-collapsed {
|
||||
display: block;
|
||||
max-height: 165rpx; /* 约 5 行 33rpx */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 渐变遮罩:绝对定位在容器底部 60px,从透明到白 */
|
||||
.expand-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 120rpx; /* 60px */
|
||||
pointer-events: none;
|
||||
}
|
||||
.gradient-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
rgba(255, 255, 255, 1) 52%
|
||||
);
|
||||
}
|
||||
|
||||
/* 展开/收起按钮:居中显示,可点击 */
|
||||
.expand-btn,
|
||||
.collapse-btn {
|
||||
position: absolute;
|
||||
bottom: 10rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx; /* 4px */
|
||||
pointer-events: auto;
|
||||
}
|
||||
/* 展开态的"收起"按钮:在文本下方居中 */
|
||||
.collapse-btn {
|
||||
position: relative;
|
||||
margin-top: 16rpx;
|
||||
left: auto;
|
||||
transform: none;
|
||||
justify-content: center;
|
||||
}
|
||||
.expand-text {
|
||||
font-size: 23rpx; /* 12px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* CSS 箭头:12x12,下/上 */
|
||||
.arrow-down,
|
||||
.arrow-up {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-right: 2rpx solid #000;
|
||||
border-bottom: 2rpx solid #000;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.arrow-up {
|
||||
transform: rotate(-135deg);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<!-- 产品信息:名称 / SKU / 国家 / 价格 / 4 列快捷信息 -->
|
||||
<view class="info-wrap">
|
||||
<!-- 产品名称 18px Bold #1A1A1A -->
|
||||
<text class="name">{{ info.name }}</text>
|
||||
|
||||
<!-- SKU + 国家 同行 12px #979797,值黑色 -->
|
||||
<view class="meta-row">
|
||||
<view class="meta-item">
|
||||
<text class="meta-label">SKU: </text>
|
||||
<text class="meta-value">{{ info.sku }}</text>
|
||||
</view>
|
||||
<view class="meta-item">
|
||||
<text class="meta-label">国家: </text>
|
||||
<text class="meta-value">{{ info.country }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 价格:¥ 和 .00 为 10px,整数 24px,全部红色 -->
|
||||
<view class="price-row">
|
||||
<text class="price-symbol">{{ info.price.symbol }}</text>
|
||||
<text class="price-integer">{{ info.price.integer }}</text>
|
||||
<text class="price-decimal">{{ info.price.decimal }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 分隔线 0.5px #F0F0F0 -->
|
||||
<view class="divider"></view>
|
||||
|
||||
<!-- 4 列快捷信息:label 10px 灰,value 13px 黑 居中 -->
|
||||
<view class="quick-info">
|
||||
<view class="quick-col" v-for="(item, index) in info.quickInfo" :key="index">
|
||||
<text class="quick-label">{{ item.label }}</text>
|
||||
<text class="quick-value">{{ item.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ProductInfo',
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.info-wrap {
|
||||
padding: 20rpx 20rpx 24rpx; /* 10px 10px 12px */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 产品名称 */
|
||||
.name {
|
||||
display: block;
|
||||
font-size: 35rpx; /* 18px */
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
line-height: 50rpx; /* 26px */
|
||||
}
|
||||
|
||||
/* SKU / 国家 同行 */
|
||||
.meta-row {
|
||||
display: flex;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.meta-item + .meta-item {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.meta-label {
|
||||
font-size: 23rpx; /* 12px */
|
||||
color: #979797;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.meta-value {
|
||||
font-size: 23rpx;
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* 价格 */
|
||||
.price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.price-symbol,
|
||||
.price-decimal {
|
||||
font-size: 19rpx; /* 10px */
|
||||
color: #ff0000;
|
||||
font-weight: 700;
|
||||
}
|
||||
.price-integer {
|
||||
font-size: 46rpx; /* 24px */
|
||||
color: #ff0000;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 分隔线 */
|
||||
.divider {
|
||||
height: 1rpx; /* 0.5px */
|
||||
background: #f0f0f0;
|
||||
margin-top: 26rpx; /* 13px 间隙 */
|
||||
}
|
||||
|
||||
/* 4 列快捷信息 */
|
||||
.quick-info {
|
||||
display: flex;
|
||||
margin-top: 20rpx; /* 10px */
|
||||
}
|
||||
.quick-col {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
.quick-label {
|
||||
font-size: 19rpx; /* 10px */
|
||||
color: #979797;
|
||||
line-height: 27rpx;
|
||||
}
|
||||
.quick-value {
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<!-- 产品尺码表:5 列 × 4 行,交替行背景 -->
|
||||
<view class="chart-wrap">
|
||||
<view class="header-row">
|
||||
<text class="title">产品尺码</text>
|
||||
<text class="unit">单位:{{ data.unit }}</text>
|
||||
</view>
|
||||
|
||||
<view class="table">
|
||||
<!-- 表头:bg #DFDFDF,圆角 6px -->
|
||||
<view class="row header">
|
||||
<text
|
||||
class="cell"
|
||||
v-for="(col, index) in data.columns"
|
||||
:key="index"
|
||||
>{{ col }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 数据行:偶数行(第 2、4 行)bg #F7F7F7,圆角 6px -->
|
||||
<view
|
||||
class="row"
|
||||
:class="{ alt: (index + 1) % 2 === 0 }"
|
||||
v-for="(row, index) in data.rows"
|
||||
:key="index"
|
||||
>
|
||||
<text class="cell">{{ row.size }}</text>
|
||||
<text class="cell">{{ row.shoulder }}</text>
|
||||
<text class="cell">{{ row.chest }}</text>
|
||||
<text class="cell">{{ row.length }}</text>
|
||||
<text class="cell">{{ row.sleeve }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SizeChart',
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.chart-wrap {
|
||||
padding: 30rpx 20rpx; /* 15px 10px */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 标题行:产品尺码 + 单位 */
|
||||
.header-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx; /* 10px */
|
||||
}
|
||||
.title {
|
||||
font-size: 29rpx; /* 15px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.unit {
|
||||
margin-left: 16rpx; /* 8px */
|
||||
font-size: 21rpx; /* 11px */
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
line-height: 33rpx;
|
||||
}
|
||||
|
||||
/* 表格 */
|
||||
.table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx; /* 行间距 4px */
|
||||
}
|
||||
|
||||
/* 单行 */
|
||||
.row {
|
||||
display: flex;
|
||||
height: 77rpx; /* 40px */
|
||||
align-items: center;
|
||||
border-radius: 12rpx; /* 6px */
|
||||
}
|
||||
|
||||
/* 表头行 */
|
||||
.row.header {
|
||||
background: #dfdfdf;
|
||||
}
|
||||
|
||||
/* 偶数行(交替背景) */
|
||||
.row.alt {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
/* 单元格:等宽分布 */
|
||||
.cell {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.row.header .cell {
|
||||
color: #000000;
|
||||
}
|
||||
.row:not(.header) .cell {
|
||||
opacity: 0.6;
|
||||
}
|
||||
.row:not(.header) .cell:first-child {
|
||||
opacity: 1; /* 尺码列不透明 */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<!-- 尺码选择:5 个按钮横排,选中态橙色边框+橙色文字(背景仍为浅灰) -->
|
||||
<view class="size-wrap">
|
||||
<text class="title">尺码</text>
|
||||
|
||||
<view class="size-list">
|
||||
<view
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
class="size-item"
|
||||
:class="{ active: selected === item }"
|
||||
@tap="selectSize(item)"
|
||||
>
|
||||
<text class="size-text">{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SizeSelector',
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
selected: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectSize(size) {
|
||||
this.$emit('select', size)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.size-wrap {
|
||||
padding: 30rpx 20rpx; /* 15px 10px */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 29rpx; /* 15px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
margin-bottom: 30rpx; /* 15px */
|
||||
}
|
||||
|
||||
/* 尺码列表横排 */
|
||||
.size-list {
|
||||
display: flex;
|
||||
gap: 12rpx; /* 6px */
|
||||
}
|
||||
|
||||
/* 单个尺码按钮 44x34,圆角 4px,背景 #F7F7F7 */
|
||||
.size-item {
|
||||
width: 85rpx; /* 44px */
|
||||
height: 65rpx; /* 34px */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f7f7f7;
|
||||
border: 1rpx solid transparent;
|
||||
border-radius: 8rpx; /* 4px */
|
||||
}
|
||||
|
||||
/* 选中:橙色边框 + 橙色文字(背景保持 #F7F7F7) */
|
||||
.size-item.active {
|
||||
border-color: #ff6800;
|
||||
}
|
||||
|
||||
.size-text {
|
||||
font-size: 25rpx; /* 13px */
|
||||
color: #000000;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.size-item.active .size-text {
|
||||
color: #ff6800;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,100 @@
|
||||
// 产品详情页 mock 数据(基于 Figma 设计稿 1544:530)
|
||||
|
||||
export const mockProduct = {
|
||||
id: 1,
|
||||
name: '180G牛奶丝T恤 DG120',
|
||||
sku: 'DG120',
|
||||
country: '美国',
|
||||
// 价格:符号/整数/小数 三段不同字号,全部红色 #FF0000
|
||||
price: {
|
||||
symbol: '¥',
|
||||
integer: '19',
|
||||
decimal: '.00'
|
||||
},
|
||||
// 价格下方的 4 列快捷信息
|
||||
quickInfo: [
|
||||
{ label: '生产工艺', value: '白墨烫画' },
|
||||
{ label: '发货时效', value: '48小时' },
|
||||
{ label: '印花', value: '单面印' },
|
||||
{ label: '产品编码', value: 'NS6001152' }
|
||||
]
|
||||
}
|
||||
|
||||
// 5 张图片对应 5 个指示点(mock 用同一张图)
|
||||
export const mockImages = [
|
||||
'/static/images/detail/Rectangle_194_1548_574.png',
|
||||
'/static/images/detail/Rectangle_194_1548_574.png',
|
||||
'/static/images/detail/Rectangle_194_1548_574.png',
|
||||
'/static/images/detail/Rectangle_194_1548_574.png',
|
||||
'/static/images/detail/Rectangle_194_1548_574.png'
|
||||
]
|
||||
|
||||
// 6 个颜色:第一行 4 个,第二行 2 个;默认选中"灰色"
|
||||
export const mockColors = [
|
||||
{ id: 1, name: '白色', value: '#FFFFFF' },
|
||||
{ id: 2, name: '黑色', value: '#000000' },
|
||||
{ id: 3, name: '灰色', value: '#838383' },
|
||||
{ id: 4, name: '橙色', value: '#FF6800' },
|
||||
{ id: 5, name: '藏青', value: '#0F215B' },
|
||||
{ id: 6, name: '粉色', value: '#FFB7D2' }
|
||||
]
|
||||
|
||||
// 默认选中 L
|
||||
export const mockSizes = ['S', 'M', 'L', 'XL', '2XL']
|
||||
|
||||
// 产品参数:前 3 项固定行高,"补充说明"可展开/收起
|
||||
export const mockParams = [
|
||||
{ label: '克重', value: '180g' },
|
||||
{ label: '材质', value: '纯棉' },
|
||||
{ label: '定制类型', value: '来图定制' },
|
||||
{
|
||||
label: '补充说明',
|
||||
expandable: true,
|
||||
value:
|
||||
'【 材质说明 】\n97%聚酯纤维 3%氨纶\n【 产品性能 】\n优质材料:这款露背T恤采用优质材料制成,面料柔软、轻薄贴身。 时尚外观:性感T恤设计,时尚性感,简约大方,适合大多数人的体型。 面料轻盈:舒适款式设计为您带来一个更加干净的外观,面料轻盈柔软,让您全天舒适。 轻松百搭:简单搭配外套、长裤、牛仔裤或沙滩休闲短裤,都是非常不错的选择,也可以选择就单穿,让您一直保持凉爽和放松。\n【 适用情景 】\n适用于日常生活、工作、出游、逛街等场合。\n【 洗涤说明 】\n可手洗可机洗,不要长时间浸泡,不可漂白,洗涤液温度不能超过45ºC。\n【 温馨提醒 】\n该图片展示效果仅供参考,最终效果以实物为准!由于生产批次、机器设备、纸样大小不同等客观因素原因,难以避免或将存在微小色差、位置及大小等误差,如遇以上问题均属于正常现象,将不予纳入售后处理范畴。 另外,根据各国本土政策要求,请勿上传科技单、跑水单等非正规来源面单,严禁使用侵权图案及未授权 IP、商标、赛事元素等内容。 违规订单将不予生产发货,已产生费用不予退还,相应风险与责任由下单方自行承担。感谢您的理解与配合。'
|
||||
}
|
||||
]
|
||||
|
||||
// 产品尺码表:4 行 5 列
|
||||
export const mockSizeChart = {
|
||||
unit: 'cm',
|
||||
columns: ['尺码', '肩宽', '胸围', '衣长', '袖长'],
|
||||
rows: [
|
||||
{ size: 'S', shoulder: '51', chest: '56', length: '62', sleeve: '48' },
|
||||
{ size: 'M', shoulder: '51', chest: '56', length: '62', sleeve: '48' },
|
||||
{ size: 'L', shoulder: '51', chest: '56', length: '62', sleeve: '48' },
|
||||
{ size: 'XL', shoulder: '51', chest: '56', length: '62', sleeve: '48' }
|
||||
]
|
||||
}
|
||||
|
||||
// 包装规格表:4 行 4 列,每个单元格双单位(cm + in)
|
||||
export const mockPackaging = {
|
||||
unit: 'cm',
|
||||
columns: ['尺码', '尺寸', '体积', '重量'],
|
||||
rows: [
|
||||
{
|
||||
size: 'S',
|
||||
dimension: { cm: '31.0*23.0*1.0cm', in: '12.20*9.06*0.39in' },
|
||||
volume: { cm: '713.00cm³', in: '43.51in³' },
|
||||
weight: { cm: '200.00g', in: '0.36lb' }
|
||||
},
|
||||
{
|
||||
size: 'M',
|
||||
dimension: { cm: '31.0*23.0*1.0cm', in: '12.20*9.06*0.39in' },
|
||||
volume: { cm: '713.00cm³', in: '43.51in³' },
|
||||
weight: { cm: '200.00g', in: '0.36lb' }
|
||||
},
|
||||
{
|
||||
size: 'L',
|
||||
dimension: { cm: '31.0*23.0*1.0cm', in: '12.20*9.06*0.39in' },
|
||||
volume: { cm: '713.00cm³', in: '43.51in³' },
|
||||
weight: { cm: '200.00g', in: '0.36lb' }
|
||||
},
|
||||
{
|
||||
size: 'XL',
|
||||
dimension: { cm: '31.0*23.0*1.0cm', in: '12.20*9.06*0.39in' },
|
||||
volume: { cm: '713.00cm³', in: '43.51in³' },
|
||||
weight: { cm: '200.00g', in: '0.36lb' }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,327 +1,14 @@
|
||||
/* 产品详情页样式 */
|
||||
/* 产品详情页 - 页面容器样式 */
|
||||
/* 各区块样式在 pages/product-detail/components/ 下对应组件的 <style scoped> 中 */
|
||||
|
||||
.detail-page {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
padding-bottom: 140rpx;
|
||||
min-height: 100vh;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* 图片区 */
|
||||
.detail-images {
|
||||
position: relative;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.detail-swiper {
|
||||
width: 100%;
|
||||
height: 750rpx;
|
||||
}
|
||||
|
||||
.swiper-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.swiper-emoji {
|
||||
font-size: 160rpx;
|
||||
}
|
||||
|
||||
.detail-badges {
|
||||
position: absolute;
|
||||
top: 24rpx;
|
||||
left: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.detail-badge {
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
/* 产品信息 */
|
||||
.detail-info-section {
|
||||
background: #ffffff;
|
||||
padding: 32rpx 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.detail-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.detail-code {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.detail-price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.detail-price {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: #ff6800;
|
||||
}
|
||||
|
||||
.detail-price-unit {
|
||||
font-size: 24rpx;
|
||||
color: #ff6800;
|
||||
}
|
||||
|
||||
.detail-price-original {
|
||||
font-size: 24rpx;
|
||||
color: #ccc;
|
||||
text-decoration: line-through;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
.detail-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 32rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 通用section */
|
||||
.detail-section {
|
||||
background: #ffffff;
|
||||
padding: 32rpx 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.section-label {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
/* 颜色选择 */
|
||||
.color-options {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.color-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
padding: 12rpx 20rpx;
|
||||
border-radius: 32rpx;
|
||||
border: 2rpx solid #eee;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.color-option.selected {
|
||||
border-color: #ff6800;
|
||||
background: #fff0e5;
|
||||
}
|
||||
|
||||
.color-dot {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid #fff;
|
||||
box-shadow: 0 0 0 1rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.color-name {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.color-option.selected .color-name {
|
||||
color: #ff6800;
|
||||
}
|
||||
|
||||
/* 尺码选择 */
|
||||
.size-options {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.size-option {
|
||||
min-width: 72rpx;
|
||||
text-align: center;
|
||||
padding: 16rpx 24rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8rpx;
|
||||
border: 2rpx solid transparent;
|
||||
}
|
||||
|
||||
.size-option.selected {
|
||||
background: #fff0e5;
|
||||
color: #ff6800;
|
||||
border-color: #ff6800;
|
||||
}
|
||||
|
||||
/* 参数表 */
|
||||
.params-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.param-row {
|
||||
display: flex;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.param-label {
|
||||
width: 200rpx;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.param-value {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 工艺说明 */
|
||||
.craft-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.craft-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
padding: 20rpx;
|
||||
background: #fafafa;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.craft-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.craft-emoji {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.craft-name {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
flex-shrink: 0;
|
||||
width: 120rpx;
|
||||
}
|
||||
|
||||
.craft-desc {
|
||||
flex: 1;
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.detail-bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 120rpx;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24rpx;
|
||||
gap: 16rpx;
|
||||
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.bottom-btn-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4rpx;
|
||||
width: 80rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.bottom-icon {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.bottom-icon-text {
|
||||
font-size: 18rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.bottom-btn-cart {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #fff0e5;
|
||||
color: #ff6800;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
|
||||
.bottom-btn-design {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #ff6800;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 40rpx;
|
||||
/* 区块之间的灰色分隔条:390x6px #F5F5F5 */
|
||||
.section-divider {
|
||||
width: 100%;
|
||||
height: 12rpx; /* 6px */
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
@@ -1,303 +1,113 @@
|
||||
<template>
|
||||
<!-- 产品详情页 -->
|
||||
<view class="detail-page">
|
||||
<!-- 产品图片区 -->
|
||||
<view class="detail-images">
|
||||
<swiper class="detail-swiper" :indicator-dots="true" indicator-color="rgba(255,255,255,0.4)" indicator-active-color="#FF6800" :circular="true">
|
||||
<swiper-item v-for="(item, index) in productImages" :key="index">
|
||||
<view class="swiper-img" :style="'background: ' + item.bg + ';'">
|
||||
<text class="swiper-emoji">{{ item.emoji }}</text>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="detail-badges">
|
||||
<view class="detail-badge" :style="'background: ' + item.bg + '; color: ' + item.color + ';'" v-for="(item, index) in productTags" :key="index">
|
||||
{{ item.text }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 产品详情页 - 严格按 Figma 1544:530 实现 -->
|
||||
<view class="detail-page">
|
||||
<!-- 产品图片轮播 + 指示点 -->
|
||||
<DetailSwiper :images="productImages" />
|
||||
|
||||
<!-- 产品信息 -->
|
||||
<view class="detail-info-section">
|
||||
<view class="detail-header">
|
||||
<text class="detail-name">{{ product.name }}</text>
|
||||
<text class="detail-code">SKU: {{ product.code }}</text>
|
||||
</view>
|
||||
<view class="detail-price-row">
|
||||
<text class="detail-price">¥{{ product.price }}</text>
|
||||
<text class="detail-price-unit">起</text>
|
||||
<text class="detail-price-original" v-if="product.originalPrice">¥{{ product.originalPrice }}</text>
|
||||
</view>
|
||||
<view class="detail-meta">
|
||||
<view class="meta-item">
|
||||
<text class="meta-label">起订量</text>
|
||||
<text class="meta-value">{{ product.moq }}件</text>
|
||||
</view>
|
||||
<view class="meta-item">
|
||||
<text class="meta-label">生产周期</text>
|
||||
<text class="meta-value">{{ product.leadTime }}</text>
|
||||
</view>
|
||||
<view class="meta-item">
|
||||
<text class="meta-label">工艺</text>
|
||||
<text class="meta-value">{{ product.craft }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 产品信息:名称/SKU/国家/价格/4列快捷信息 -->
|
||||
<ProductInfo :info="product" />
|
||||
|
||||
<!-- 颜色选择 -->
|
||||
<view class="detail-section">
|
||||
<text class="section-label">颜色选择</text>
|
||||
<view class="color-options">
|
||||
<view :class="'color-option ' + (selectedColor === index ? 'selected' : '')" @tap="selectColor" :data-index="index" v-for="(item, index) in colors" :key="index">
|
||||
<view class="color-dot" :style="'background: ' + item.value + ';'"></view>
|
||||
<!-- 灰色分隔条 -->
|
||||
<view class="section-divider"></view>
|
||||
|
||||
<text class="color-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 颜色选择 -->
|
||||
<ColorSelector
|
||||
:list="colors"
|
||||
:selected-id="selectedColorId"
|
||||
@select="selectColor"
|
||||
/>
|
||||
|
||||
<!-- 尺码选择 -->
|
||||
<view class="detail-section">
|
||||
<text class="section-label">尺码选择</text>
|
||||
<view class="size-options">
|
||||
<view :class="'size-option ' + (selectedSize === item ? 'selected' : '')" @tap="selectSize" :data-size="item" v-for="(item, index) in sizes" :key="index">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 灰色分隔条 -->
|
||||
<view class="section-divider"></view>
|
||||
|
||||
<!-- 产品详情 -->
|
||||
<view class="detail-section">
|
||||
<text class="section-label">产品参数</text>
|
||||
<view class="params-table">
|
||||
<view class="param-row" v-for="(item, index) in productParams" :key="index">
|
||||
<text class="param-label">{{ item.label }}</text>
|
||||
<!-- 尺码选择 -->
|
||||
<SizeSelector
|
||||
:list="sizes"
|
||||
:selected="selectedSize"
|
||||
@select="selectSize"
|
||||
/>
|
||||
|
||||
<text class="param-value">{{ item.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 灰色分隔条 -->
|
||||
<view class="section-divider"></view>
|
||||
|
||||
<!-- 工艺说明 -->
|
||||
<view class="detail-section">
|
||||
<text class="section-label">工艺说明</text>
|
||||
<view class="craft-info">
|
||||
<view class="craft-card" v-for="(item, index) in crafts" :key="index">
|
||||
<view class="craft-icon" :style="'background: ' + item.bg + ';'">
|
||||
<text class="craft-emoji">{{ item.emoji }}</text>
|
||||
</view>
|
||||
<!-- 产品参数(含可展开的补充说明) -->
|
||||
<ParamsTable :list="productParams" />
|
||||
|
||||
<text class="craft-name">{{ item.name }}</text>
|
||||
<!-- 灰色分隔条 -->
|
||||
<view class="section-divider"></view>
|
||||
|
||||
<text class="craft-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 产品尺码表 -->
|
||||
<SizeChart :data="sizeChart" />
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="detail-bottom-bar safe-bottom">
|
||||
<view class="bottom-btn-icon" @tap="toggleFav">
|
||||
<text class="bottom-icon">{{ isFav ? '❤️' : '🤍' }}</text>
|
||||
<text class="bottom-icon-text">收藏</text>
|
||||
</view>
|
||||
<view class="bottom-btn-icon" @tap="contactService">
|
||||
<text class="bottom-icon">💬</text>
|
||||
<text class="bottom-icon-text">客服</text>
|
||||
</view>
|
||||
<view class="bottom-btn-cart" @tap="addToCart">
|
||||
<text>加入清单</text>
|
||||
</view>
|
||||
<view class="bottom-btn-design" @tap="startDesign">
|
||||
<text>立即定制</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 灰色分隔条 -->
|
||||
<view class="section-divider"></view>
|
||||
|
||||
<!-- 包装规格表 -->
|
||||
<PackagingSpec :data="packaging" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailSwiper from './components/DetailSwiper.vue'
|
||||
import ProductInfo from './components/ProductInfo.vue'
|
||||
import ColorSelector from './components/ColorSelector.vue'
|
||||
import SizeSelector from './components/SizeSelector.vue'
|
||||
import ParamsTable from './components/ParamsTable.vue'
|
||||
import SizeChart from './components/SizeChart.vue'
|
||||
import PackagingSpec from './components/PackagingSpec.vue'
|
||||
|
||||
import {
|
||||
mockProduct,
|
||||
mockImages,
|
||||
mockColors,
|
||||
mockSizes,
|
||||
mockParams,
|
||||
mockSizeChart,
|
||||
mockPackaging
|
||||
} from './mock.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
productId: null,
|
||||
product: {
|
||||
name: '180G牛奶丝T恤 DG120',
|
||||
code: 'DG120',
|
||||
price: '28.00',
|
||||
originalPrice: '35.00',
|
||||
moq: 1,
|
||||
leadTime: '48小时',
|
||||
craft: '烫画/数码直喷'
|
||||
},
|
||||
productImages: [
|
||||
{
|
||||
bg: '#F5F5F5',
|
||||
emoji: '👕'
|
||||
},
|
||||
{
|
||||
bg: '#E8E8E8',
|
||||
emoji: '👕'
|
||||
},
|
||||
{
|
||||
bg: '#F0F0F0',
|
||||
emoji: '👕'
|
||||
}
|
||||
],
|
||||
productTags: [
|
||||
{
|
||||
text: '可定制',
|
||||
bg: '#FFF0E5',
|
||||
color: '#FF6800'
|
||||
},
|
||||
{
|
||||
text: '现货',
|
||||
bg: '#E5F5FF',
|
||||
color: '#1890FF'
|
||||
},
|
||||
{
|
||||
text: '快返',
|
||||
bg: '#F0FFE5',
|
||||
color: '#52C41A'
|
||||
}
|
||||
],
|
||||
colors: [
|
||||
{
|
||||
name: '白色',
|
||||
value: '#FFFFFF'
|
||||
},
|
||||
{
|
||||
name: '黑色',
|
||||
value: '#1a1a1a'
|
||||
},
|
||||
{
|
||||
name: '灰色',
|
||||
value: '#999999'
|
||||
},
|
||||
{
|
||||
name: '橙色',
|
||||
value: '#FF6800'
|
||||
},
|
||||
{
|
||||
name: '藏青',
|
||||
value: '#1B365D'
|
||||
},
|
||||
{
|
||||
name: '军绿',
|
||||
value: '#4A5D23'
|
||||
}
|
||||
],
|
||||
selectedColor: 0,
|
||||
sizes: ['XS', 'S', 'M', 'L', 'XL', '2XL', '3XL'],
|
||||
selectedSize: 'M',
|
||||
productParams: [
|
||||
{
|
||||
label: '克重',
|
||||
value: '180g'
|
||||
},
|
||||
{
|
||||
label: '材质',
|
||||
value: '牛奶丝(改性聚酯纤维)'
|
||||
},
|
||||
{
|
||||
label: '版型',
|
||||
value: '常规版'
|
||||
},
|
||||
{
|
||||
label: '领型',
|
||||
value: '圆领'
|
||||
},
|
||||
{
|
||||
label: '袖型',
|
||||
value: '短袖'
|
||||
},
|
||||
{
|
||||
label: '适用工艺',
|
||||
value: '烫画、数码直喷、刺绣'
|
||||
},
|
||||
{
|
||||
label: '可售区域',
|
||||
value: '全球'
|
||||
},
|
||||
{
|
||||
label: '洗涤说明',
|
||||
value: '冷水机洗,不可漂白'
|
||||
}
|
||||
],
|
||||
crafts: [
|
||||
{
|
||||
name: '烫画',
|
||||
desc: '色彩鲜艳,适合复杂图案,成本低',
|
||||
emoji: '🎨',
|
||||
bg: '#FFF0E5'
|
||||
},
|
||||
{
|
||||
name: '数码直喷',
|
||||
desc: '触感柔软,透气性好,适合大面积印花',
|
||||
emoji: '🖨️',
|
||||
bg: '#E5F5FF'
|
||||
},
|
||||
{
|
||||
name: '刺绣',
|
||||
desc: '质感高级,经久耐用,适合logo',
|
||||
emoji: '🪡',
|
||||
bg: '#F0FFE5'
|
||||
}
|
||||
],
|
||||
isFav: false
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.setData({
|
||||
productId: options.id
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectColor(e) {
|
||||
this.setData({
|
||||
selectedColor: e.currentTarget.dataset.index
|
||||
});
|
||||
},
|
||||
|
||||
selectSize(e) {
|
||||
this.setData({
|
||||
selectedSize: e.currentTarget.dataset.size
|
||||
});
|
||||
},
|
||||
|
||||
toggleFav() {
|
||||
this.setData({
|
||||
isFav: !this.isFav
|
||||
});
|
||||
uni.showToast({
|
||||
title: this.isFav ? '已收藏' : '已取消',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
|
||||
contactService() {
|
||||
uni.showToast({
|
||||
title: '客服功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
|
||||
addToCart() {
|
||||
uni.showToast({
|
||||
title: '已加入清单',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
|
||||
startDesign() {
|
||||
uni.showToast({
|
||||
title: '定制功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
components: {
|
||||
DetailSwiper,
|
||||
ProductInfo,
|
||||
ColorSelector,
|
||||
SizeSelector,
|
||||
ParamsTable,
|
||||
SizeChart,
|
||||
PackagingSpec
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
productId: null,
|
||||
product: mockProduct,
|
||||
productImages: mockImages,
|
||||
colors: mockColors,
|
||||
// 默认选中"灰色"(id=3),与 Figma 设计稿一致
|
||||
selectedColorId: 3,
|
||||
sizes: mockSizes,
|
||||
// 默认选中 L,与 Figma 设计稿一致
|
||||
selectedSize: 'L',
|
||||
productParams: mockParams,
|
||||
sizeChart: mockSizeChart,
|
||||
packaging: mockPackaging
|
||||
}
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.id) {
|
||||
this.productId = options.id
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectColor(id) {
|
||||
this.selectedColorId = id
|
||||
},
|
||||
selectSize(size) {
|
||||
this.selectedSize = size
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import './product-detail.css';
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user