hulai-website/components/home/DifferentiatorList.vue

146 行
4.8 KiB
Vue

<template>
<section class="section section--warm">
<div class="container">
<CommonSectionTitle :title="st('home.differentiator', '为什么选择呼籁')" :label="st('home.differentiator', 'WHY HULAI', 'label')" :subtitle="st('home.differentiator', '不只是包车,是一套成熟的旅行服务体系', 'subtitle')" />
<div class="diff-grid">
<div v-for="(item, index) in itemsWithBg" :key="item.title" class="diff-item">
<div class="diff-bg">
<img :src="item.bgImage" :alt="item.title" loading="lazy" />
</div>
<div class="diff-content">
<div class="diff-icon" v-html="icons[index % icons.length]" />
<h3 class="diff-title">{{ item.title }}</h3>
<p class="diff-desc">{{ item.description }}</p>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup>
const props = defineProps({
items: { type: Array, required: true },
})
const st = await useSectionTitles()
const bgImages = [
'/images/seasons/summer-hero.jpg',
'/images/seasons/summer-car.jpg',
'/images/seasons/summer-river.jpg',
'/images/seasons/autumn-forest.jpg',
'/images/seasons/autumn-lake.jpg',
'/images/seasons/winter-hero.jpg',
]
const itemsWithBg = computed(() =>
props.items.map((item, i) => ({
...item,
bgImage: bgImages[i % bgImages.length],
}))
)
const icons = [
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21l9-18 9 18"/><path d="M12 3v18"/><path d="M3 21h18"/></svg>',
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="3" width="15" height="13" rx="2"/><polygon points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>',
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>',
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>',
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>',
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2z"/><path d="M22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg>',
]
</script>
<style lang="less" scoped>
.diff-grid {
display: grid;
grid-template-columns: 1fr;
gap: @space-lg;
.respond-md({
grid-template-columns: repeat(2, 1fr);
});
.respond-lg({
grid-template-columns: repeat(3, 1fr);
});
}
.diff-item {
position: relative;
border-radius: @border-radius-lg;
overflow: hidden;
border: 1px solid @color-border;
transition: box-shadow 0.35s cubic-bezier(0.23, 1, 0.32, 1), transform 0.35s cubic-bezier(0.23, 1, 0.32, 1);
&:hover {
box-shadow: @shadow-lg;
transform: translateY(-3px);
.diff-bg img {
transform: scale(1.05);
}
.diff-icon {
color: @color-primary;
background: rgba(255, 255, 255, 0.95);
}
}
}
// 浅色背景图
.diff-bg {
position: absolute;
inset: 0;
z-index: 0;
img {
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0.15;
filter: saturate(0.6);
transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.4s ease;
}
// 叠加一层白色渐变让文字区域更清晰
&::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.7) 0%, rgba(255,255,255,0.4) 100%);
}
}
.diff-content {
position: relative;
z-index: 1;
padding: @space-xl @space-lg;
}
.diff-icon {
display: flex;
align-items: center;
justify-content: center;
width: 56px;
height: 56px;
border-radius: @border-radius-lg;
background: rgba(240, 247, 244, 0.9);
color: @color-primary-light;
margin-bottom: @space-lg;
transition: color @transition-base, background @transition-base;
}
.diff-title {
font-size: @font-size-lg;
color: @color-text-primary;
margin-bottom: @space-sm;
}
.diff-desc {
font-size: @font-size-base;
color: @color-text-secondary;
line-height: @line-height-relaxed;
}
</style>