init
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<script setup>
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
|
||||
import { testimonials as defaultTestimonials } from "~/data/home";
|
||||
|
||||
const props = defineProps({
|
||||
testimonials: {
|
||||
type: Array,
|
||||
default: () => defaultTestimonials,
|
||||
},
|
||||
routes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
sectionId: {
|
||||
type: String,
|
||||
default: "testimonials",
|
||||
},
|
||||
});
|
||||
|
||||
const currentIndex = ref(0);
|
||||
const isPaused = ref(false);
|
||||
let timer;
|
||||
|
||||
const current = computed(() => props.testimonials[currentIndex.value]);
|
||||
|
||||
const goToSlide = (index) => {
|
||||
currentIndex.value = index;
|
||||
};
|
||||
|
||||
const goToPrev = () => {
|
||||
currentIndex.value =
|
||||
currentIndex.value === 0 ? props.testimonials.length - 1 : currentIndex.value - 1;
|
||||
};
|
||||
|
||||
const goToNext = () => {
|
||||
currentIndex.value =
|
||||
currentIndex.value === props.testimonials.length - 1 ? 0 : currentIndex.value + 1;
|
||||
};
|
||||
|
||||
const startAutoplay = () => {
|
||||
timer = window.setInterval(() => {
|
||||
if (!isPaused.value) {
|
||||
goToNext();
|
||||
}
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
startAutoplay();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.clearInterval(timer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section
|
||||
:id="sectionId"
|
||||
class="bg-white py-20"
|
||||
@mouseenter="isPaused = true"
|
||||
@mouseleave="isPaused = false"
|
||||
>
|
||||
<div class="container-gm">
|
||||
<div class="flex flex-col gap-5 md:flex-row md:items-end md:justify-between" data-reveal>
|
||||
<div class="max-w-3xl">
|
||||
<p class="text-sm uppercase tracking-[0.3em] text-[#a1a1a1]">Voice</p>
|
||||
<h2 class="section-title mt-4">客户真实评价,见证服务品质</h2>
|
||||
<p class="mt-3 text-[#777]">
|
||||
从真实客户视角补充信任背书,进一步强化团队专业度和落地能力。
|
||||
</p>
|
||||
</div>
|
||||
<SectionRouteLinks :routes="routes" />
|
||||
</div>
|
||||
|
||||
<div class="mx-auto mt-12 max-w-3xl text-center" data-reveal>
|
||||
<div class="mx-auto flex h-16 w-16 items-center justify-center rounded-lg bg-gm-light text-xl font-semibold text-gm-green">
|
||||
{{ current?.name.slice(0, 1) }}
|
||||
</div>
|
||||
|
||||
<transition
|
||||
mode="out-in"
|
||||
enter-active-class="transition duration-500 ease-out"
|
||||
enter-from-class="translate-y-3 opacity-0"
|
||||
enter-to-class="translate-y-0 opacity-100"
|
||||
leave-active-class="transition duration-300 ease-in"
|
||||
leave-from-class="translate-y-0 opacity-100"
|
||||
leave-to-class="-translate-y-2 opacity-0"
|
||||
>
|
||||
<div :key="current.id" class="mt-6">
|
||||
<blockquote class="text-balance text-lg italic leading-8 text-[#555] md:text-xl">
|
||||
“{{ current.quote }}”
|
||||
</blockquote>
|
||||
<p class="mt-6 text-base font-semibold text-[#262626]">{{ current.name }}</p>
|
||||
<p class="text-sm text-[#9b9b9b]">{{ current.title }}</p>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 flex items-center justify-center gap-2">
|
||||
<button
|
||||
v-for="(item, index) in props.testimonials"
|
||||
:key="item.id"
|
||||
type="button"
|
||||
:aria-label="`切换到第 ${index + 1} 条评价`"
|
||||
class="size-3 rounded-full transition-all duration-300"
|
||||
:class="index === currentIndex ? 'bg-gm-green' : 'bg-gray-300'"
|
||||
@click="goToSlide(index)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex items-center justify-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
class="flex size-10 items-center justify-center rounded-full border border-gm-border text-[#666] transition hover:border-gm-green hover:text-gm-green"
|
||||
aria-label="上一条评价"
|
||||
@click="goToPrev"
|
||||
>
|
||||
←
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="flex size-10 items-center justify-center rounded-full border border-gm-border text-[#666] transition hover:border-gm-green hover:text-gm-green"
|
||||
aria-label="下一条评价"
|
||||
@click="goToNext"
|
||||
>
|
||||
→
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user