You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
4.3 KiB

3 months ago
<template>
<div class="product-list">
<div class="product-grid">
<div v-for="product in products" :key="product.id" class="product-card">
<div class="product-img">
2 months ago
<a :href="`/Detail/${product.id}`" :to="`/Detail/${product.id}`">
3 months ago
<img
2 months ago
v-lazy="product.headimg"
:alt="product.title"
3 months ago
class="product-pic"
/>
</a>
</div>
<div class="product-info">
<div class="flex-between">
<div class="product-price">
2 months ago
<span class="current-price">¥{{ product.price / 100 }}</span>
<span class="original-price" v-if="product.market_price"
>¥{{ product.market_price / 100 }}</span
3 months ago
>
</div>
<div class="product-sales" v-if="product.sales">
2 months ago
<span>已售 {{ product.sales_number }} </span>
3 months ago
</div>
</div>
<h3 class="product-name">
2 months ago
<a :href="`/Detail/${product.id}`" :to="`/Detail/${product.id}`">
2 months ago
{{ product.title }}
3 months ago
</a>
</h3>
<div class="product-actions">
<el-button
type="primary"
size="small"
3 months ago
style="background-color: #6a8a27; border: none"
3 months ago
@click="addToCart(product)"
>
<el-icon name="el-icon-shopping-cart"></el-icon>
</el-button>
</div>
</div>
</div>
</div>
<!-- 无商品时显示 -->
<div class="no-products" v-if="products.length === 0">
<el-empty description="暂无相关商品"></el-empty>
</div>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
name: "ProductList",
props: {
products: {
type: Array,
default: () => [],
},
},
methods: {
...mapActions(["addToCart"]),
addToCart(product) {
// 检查用户是否登录
if (!this.$store.getters.isUserLogin) {
this.$confirm("您尚未登录,是否前往登录?", "提示", {
confirmButtonText: "登录",
cancelButtonText: "取消",
type: "info",
})
.then(() => {
this.$router.push({
path: "/login",
query: { redirect: this.$route.fullPath },
});
})
.catch(() => {
// 取消登录
});
return;
}
this.addToCart({
id: product.id,
name: product.name,
price: product.price,
image: product.image,
quantity: 1,
});
this.$message.success("已加入购物车");
},
},
};
</script>
<style lang="scss" scoped>
.product-list {
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
.product-card {
border: 1px solid #eaeaea;
border-radius: 8px;
overflow: hidden;
transition: all 0.3s ease;
padding: 10px;
&:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.product-img {
height: 250px;
overflow: hidden;
.product-pic {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
&:hover {
transform: scale(1.05);
}
}
}
.product-info {
padding: 10px;
.product-name {
font-size: 14px;
line-height: 20px;
min-height: 40px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
margin-bottom: 10px;
a {
color: #333;
&:hover {
color: #409eff;
}
}
}
.product-price {
margin-bottom: 15px;
.current-price {
color: #ff4400;
font-size: 16px;
font-weight: 700;
}
.original-price {
color: #999;
font-size: 12px;
text-decoration: line-through;
margin-left: 8px;
}
}
.product-actions {
margin-bottom: 10px;
}
.product-sales {
font-size: 12px;
color: #999;
margin-bottom: 15px;
}
}
}
.no-products {
padding: 50px 0;
text-align: center;
}
}
</style>