87 lines
1.6 KiB
Vue
87 lines
1.6 KiB
Vue
<template>
|
||
<el-card class="product-card" @click="handleClick">
|
||
<template #header>
|
||
<!-- Image -->
|
||
<el-image class="product-image" :src="imageUrl" fit="contain" />
|
||
</template>
|
||
|
||
<div class="card-body">
|
||
<!-- Name -->
|
||
<div class="text-center">
|
||
<span class="product-name">{{ name }}</span>
|
||
</div>
|
||
<!-- Description -->
|
||
<div class="card-description text-left opacity-25">{{ description }}</div>
|
||
</div>
|
||
</el-card>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
interface Props {
|
||
name: string;
|
||
description: string;
|
||
imageUrl: string;
|
||
id?: string | number;
|
||
slug?: string;
|
||
}
|
||
|
||
const props = defineProps<Props>();
|
||
const localePath = useLocalePath();
|
||
|
||
const handleClick = () => {
|
||
// 优先使用 slug,如果没有则使用 id
|
||
const routeParam = props.slug || props.id;
|
||
if (routeParam) {
|
||
navigateTo(localePath(`/products/${routeParam}`));
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.product-card {
|
||
width: 30%;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
text-align: center;
|
||
}
|
||
|
||
.product-card:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.product-name {
|
||
font-size: 1rem;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.card-description {
|
||
font-size: 0.8rem;
|
||
margin-top: 5px;
|
||
}
|
||
|
||
.product-card .el-image {
|
||
height: 150px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.card-body {
|
||
margin: 10px auto;
|
||
padding: 0px auto;
|
||
height: 100px;
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 1200px) {
|
||
.product-card {
|
||
width: 45%;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.product-card {
|
||
width: 90%;
|
||
}
|
||
}
|
||
</style>
|