feat: 商品列表、商品详情优化

This commit is contained in:
2026-07-27 18:12:29 +08:00
parent eed5c3fe03
commit 8542b437ad
12 changed files with 794 additions and 156 deletions
@@ -1,20 +1,62 @@
<template>
<main class="detail-page">
<van-nav-bar title="商品详情" left-arrow @click-left="$router.back()" />
<van-image class="product-image" :src="product.image" fit="cover" />
<header class="detail-top">
<van-icon name="arrow-left" @click="$router.back()" />
<h1>商品详情</h1>
<div>
<van-icon name="star-o" />
<van-icon name="share-o" />
</div>
</header>
<section class="image-section">
<van-image class="product-image" :src="product.image" fit="cover" />
<span class="image-index">1/5</span>
</section>
<section class="product-info">
<h1>{{ product.name }}</h1>
<h2>{{ product.name }}</h2>
<p>{{ product.detail }}</p>
<div><b>¥{{ product.price }}</b><del>¥{{ product.originPrice }}</del><van-tag type="danger" plain>{{ product.tag }}</van-tag></div>
<div class="price-row">
<b>¥{{ product.price }}</b>
<del>¥{{ product.originPrice }}</del>
<van-tag class="point-tag" plain type="danger">{{ product.tag }}</van-tag>
</div>
</section>
<van-cell-group inset title="商品服务">
<van-cell title="正品保障" value="极速发货 · 售后无忧" />
<van-cell title="配送" value="满 99 元免配送费" />
</van-cell-group>
<section class="option-card">
<van-cell title="选择规格" value="默认规格" is-link />
<van-cell title="商品数量">
<template #right-icon>
<div class="quantity-box">
<van-stepper v-model="count" integer min="1" button-size="28" input-width="42" />
<span>库存充足</span>
</div>
</template>
</van-cell>
</section>
<section class="service-card">
<h3>商品服务</h3>
<van-cell title="正品保障" value="品质保证,安心兑换" is-link>
<template #icon><van-icon class="service-icon" name="shield-o" /></template>
</van-cell>
<van-cell title="配送" value="满 99 元免配送费" is-link>
<template #icon><van-icon class="service-icon" name="logistics" /></template>
</van-cell>
</section>
<section class="detail-content">
<h2>商品详情</h2>
<p>{{ product.desc }}</p>
<h3>商品详情</h3>
<div class="feature-grid">
<article v-for="item in features" :key="item.title">
<span><van-icon :name="item.icon" /></span>
<b>{{ item.title }}</b>
<p>{{ item.desc }}</p>
</article>
</div>
</section>
<van-goods-action>
<van-goods-action-icon icon="chat-o" text="客服" dot />
<van-goods-action-icon icon="cart-o" text="购物车" badge="5" @click="$router.push('/joyful-selection/cart')" />
@@ -30,19 +72,268 @@ import { getJoyfulProduct } from '../product-data'
export default {
name: 'JoyfulSelectionProductDetail',
data: () => ({
count: 1,
features: [
{ icon: 'music-o', title: '舒适半入耳设计', desc: '长时间佩戴更舒适' },
{ icon: 'bar-chart-o', title: '高清音质', desc: '清晰稳定的聆听体验' },
{ icon: 'battery-o', title: '长续航', desc: '单次可用约 5 小时' },
{ icon: 'cluster-o', title: '蓝牙 5.0', desc: '稳定连接,低延迟' }
]
}),
computed: {
product() { return getJoyfulProduct(this.$route.query.id) }
}
}
</script>
<style scoped>
.detail-page { min-height: 100vh; padding-bottom: 56px; background: #f7f7f7; }
.product-image { display: block; width: 100%; height: 310px; background: #fff; }
.product-info, .detail-content { margin: 10px 12px; padding: 14px; border-radius: 10px; background: #fff; }
.product-info h1 { margin: 0 0 8px; font-size: 17px; }
.product-info p, .detail-content p { color: #777; font-size: 12px; line-height: 1.6; }
.product-info b { margin-right: 8px; color: #ff5b20; font-size: 21px; }
.product-info del { margin-right: 9px; color: #aaa; font-size: 11px; }
.detail-content h2 { margin: 0; font-size: 15px; }
<style scoped lang="less">
.detail-page {
min-height: 100vh;
padding-bottom: 60px;
background: #f5f5f5;
}
.detail-top {
position: fixed;
z-index: 10;
top: 0;
right: 0;
left: 0;
display: flex;
height: 54px;
align-items: center;
justify-content: space-between;
padding: 0 18px;
color: #111;
background: rgba(247, 248, 250, .88);
backdrop-filter: blur(8px);
}
.detail-top > .van-icon {
font-size: 26px;
}
.detail-top h1 {
margin: 0;
font-size: 18px;
font-weight: 700;
}
.detail-top div {
display: flex;
gap: 20px;
}
.detail-top div .van-icon {
font-size: 24px;
}
.image-section {
position: relative;
padding-top: 54px;
background: #eef0f4;
}
.product-image {
display: block;
width: 100%;
height: 365px;
background: #fff;
}
.image-index {
position: absolute;
right: 18px;
bottom: 26px;
min-width: 44px;
padding: 5px 10px;
border-radius: 16px;
color: #fff;
font-size: 14px;
line-height: 1;
text-align: center;
background: rgba(0, 0, 0, .36);
}
.product-info,
.option-card,
.service-card,
.detail-content {
margin: 10px 12px 0;
border-radius: 12px;
background: #fff;
}
.product-info {
margin-top: -4px;
padding: 18px 16px 16px;
}
.product-info h2 {
margin: 0 0 12px;
color: #111;
font-size: 20px;
font-weight: 700;
line-height: 1.25;
}
.product-info p {
margin: 0;
color: #777;
font-size: 14px;
line-height: 1.7;
}
.price-row {
display: flex;
align-items: center;
gap: 12px;
margin-top: 17px;
}
.price-row b {
color: #ff5b20;
font-size: 24px;
font-weight: 700;
line-height: 1;
}
.price-row del {
color: #999;
font-size: 13px;
}
.point-tag {
color: #ff2f3a;
border-color: #ff2f3a;
font-size: 13px;
}
.option-card {
overflow: hidden;
padding: 4px 16px;
}
.option-card ::v-deep .van-cell {
padding: 15px 0;
}
.option-card ::v-deep .van-cell::after {
right: 0;
left: 0;
}
.option-card ::v-deep .van-cell__title {
color: #222;
font-size: 15px;
font-weight: 700;
}
.option-card ::v-deep .van-cell__value {
color: #888;
font-size: 14px;
}
.quantity-box {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6px;
}
.quantity-box span {
color: #999;
font-size: 12px;
}
.service-card {
overflow: hidden;
padding: 16px 16px 9px;
}
.service-card h3,
.detail-content h3 {
margin: 0 0 13px;
color: #111;
font-size: 16px;
font-weight: 700;
}
.service-card ::v-deep .van-cell {
padding: 11px 0;
}
.service-card ::v-deep .van-cell::after {
display: none;
}
.service-card ::v-deep .van-cell__title {
color: #222;
font-size: 15px;
}
.service-card ::v-deep .van-cell__value {
color: #888;
font-size: 14px;
}
.service-icon {
margin-right: 10px;
color: #ff5b20;
font-size: 20px;
}
.detail-content {
padding: 16px;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
}
.feature-grid article {
min-width: 0;
text-align: center;
}
.feature-grid span {
display: flex;
width: 48px;
height: 48px;
align-items: center;
justify-content: center;
margin: 0 auto 10px;
border-radius: 50%;
color: #2d558c;
background: #f0f2f6;
}
.feature-grid span .van-icon {
font-size: 25px;
}
.feature-grid b {
display: block;
overflow: hidden;
color: #222;
font-size: 12px;
line-height: 1.35;
text-overflow: ellipsis;
white-space: nowrap;
}
.feature-grid p {
display: -webkit-box;
overflow: hidden;
margin: 4px 0 0;
color: #888;
font-size: 11px;
line-height: 1.35;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
</style>