Skip to content

实现带进度条的 tabs

预览

picture-1

实现

html
<div class="flex gap-x-[20px]">
  <div class="w-[384px]">
    <div
      v-for="(item, index) in tabList"
      :key="index"
      class="p-[10px] mb-[30px] text-[#a1a1aa] cursor-pointer border-[1px] border-[#a1a1aa] hover:border-white"
      :class="[active === index ? activeClass : '']"
      @click="handleSwitch(index)"
    >
      <div class="mb-[10px] text-[18px]">{{ item.title }}</div>
      <div class="mb-[10px] text-[16px]">{{ item.content }}</div>
      <div class="w-fit text-[14px]">Learn more -></div>
    </div>
  </div>
  <div class="flex-1 relative">
    <div class="process-top transition-all" :style="{ width: `${percent}%` }" />
    <img class="w-full h-[400px]" :src="tabList[active].image" />
  </div>
</div>
css
.process-top {
  background: linear-gradient(90deg, #407cff, #da8bff, #fb7185);
  content: "";
  height: 2px;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
}
vue
<script setup>
import { ref, watch, onUnmounted } from "#imports";
import image1 from "@/assets/image/image-1.jpg";
import image2 from "@/assets/image/image-2.jpg";
import image3 from "@/assets/image/image-3.jpg";

const active = ref(0);
const percent = ref(0);
const activeClass = ref("!text-white !border-white");
const tabList = [
  // ...
];

const timer = ref(false);
const timeCalc = () => {
  timer.value = setInterval(() => {
    // 这里按照具体展示时间来将时间刻度切细, e.g.: 6s
    const temp = percent.value + Number(((1 / 6) * 10).toFixed(2));
    if (temp > 100) {
      percent.value = 100;
    } else {
      percent.value = temp;
    }

    if (percent.value === 100) {
      clearInterval(timer.value);
    }
  }, 100);
};
const handleSwitch = (index) => {
  if (index === active.value) return;
  clearInterval(timer.value);
  percent.value = 0;
  active.value = index;
  setTimeout(() => {
    timeCalc();
  }, 200);
};

// 进度条100%后自动切换下一个
watch(percent, () => {
  if (percent.value === 100) {
    percent.value = 0;
    active.value = active.value + 1 > tabList.length - 1 ? 0 : active.value + 1;
    setTimeout(() => {
      timeCalc();
    }, 200);
  }
});

timeCalc();

// 组件卸载后自动清除定时器
onUnmounted(() => {
  clearInterval(timer.value);
});
</script>
2025( )
今日 8.33%
本周 42.86%
本月 48.39%
本年 4.11%
Powered by Snowinlu | Copyright © 2024- | MIT License