效果
开始效果

即将结束

结束

码
<template>
<q-carousel
v-model="carouselInfo.activeName"
transition-prev="scale"
transition-next="scale"
swipeable
animated
:autoplay="carousel.length > 1 ? carouselInfo.nextTime : 0"
:infinite="carousel.length > 1"
:navigation="carousel.length > 1"
padding
arrows
height="300px"
class="bg-primary text-white shadow-1 rounded-borders"
>
<template v-slot:navigation-icon="{ active, onClick }">
<q-btn flat size="sm" v-if="active" @click="onClick" :ripple="false">
<div
class="caruse-progress carouse-progress-active relative-position"
></div>
</q-btn>
<q-btn flat size="sm" v-else @click="onClick" :ripple="false">
<div class="caruse-progress relative-position"></div>
</q-btn>
</template>
<q-carousel-slide
v-for="(it, i) in carousel"
:name="it.name"
class="column no-wrap flex-center"
>
<q-icon name="style" size="56px" />
<div class="q-mt-md text-center">
{{ it.text }}
</div>
</q-carousel-slide>
</q-carousel>
</template>
<script setup>
import { reactive, ref } from "vue";
const carouselInfo = reactive({
activeName: "sg1",
nextTime: 3000,
});
const cssNextTime = carouselInfo.nextTime + "ms";
const carousel = [
{
name: "sg1",
text: "哦吼",
},
{
name: "sg2",
text: "哦吼哦吼",
},
{
name: "sg3",
text: "哦吼哦吼哦吼",
},
{
name: "sg4",
text: "哦吼哦吼哦吼哦吼哦吼",
},
];
</script>
<style lang="sass" scoped>
.caruse-progress
width: 30px
height: 3px
background: rgba(0,0,0,.2)
.carouse-progress-active
&::after
content: '',
width: 0
height: 100%
background: white
position: absolute
left: 0
top: 0
animation: v-bind('cssNextTime') linear carouse-progress
@keyframes carouse-progress
from
width: 0
to
width: 100%
</style>