console
import { createApp } from 'https://ax.minicg.com/pvue.es.js';
const { log, dir, table, clear, warn, error } = console; clear();
createApp({
Slideshow
}).mount()
function Slideshow(props={}) {
return {
$template: '#Slideshow',
idx: 0,
ticker: null,
delay: props.delay || 2000,
data: props.images,
next() {
this.idx = (this.idx + 1) % this.data.length
},
prev() {
this.idx = (this.idx - 1 + this.data.length) % this.data.length
},
goto(index) {
this.idx = index
},
play() {
this.ticker = setInterval(this.next, this.delay)
},
stop() {
clearInterval(this.ticker)
},
mounted() {
this.play()
},
}
}
<div v-scope class="w-full h-full flex justify-center items-center gap-10">
<div v-scope="
Slideshow({
delay: 1000,
images: [
{ img:'https://ax.minicg.com/images/avatar/01.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/02.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/03.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/04.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/05.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/06.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/07.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/avatar/08.jpg', alt:'' },
]
})
"></div>
<div v-scope="
Slideshow({
delay: 1000,
images: [
{ img:'https://ax.minicg.com/images/pets/01.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/pets/02.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/pets/03.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/pets/04.jpg', alt:'' },
{ img:'https://ax.minicg.com/images/pets/05.jpg', alt:'' },
]
})
"></div>
</div>
<template id="Slideshow">
<div class="w-80 bg-white rounded-xl shadow-lg flex flex-col items-center gap-6 py-10 duration-500 group" @vue:mounted="mounted" @mouseover="stop" @mouseleave="play">
<ul class="mx-auto grid rounded-full w-48 overflow-hidden bg-white border duration-100 group-hover:border-indigo-200 group-hover:border-[12px]">
<li v-for="(item, index) in data" style="grid-area:1/-1;" class="place-items-center">
<img :class="[`w-auto duration-500`, index===idx?'opacity-100':'opacity-0 rotate-180']" :src="item.img">
</li>
</ul>
<p class="text-sm">当前索引: {{idx}}</p>
<ul class="flex gap-2 text-indigo-500">
<li v-for="(item, index) in data" @click="goto(index)" class="cursor-pointer">
<span :class="['block bg-indigo-500 w-2 h-2 rounded-full', index===idx?'opacity-100':'opacity-20']"></span>
</li>
</ul>
<div class="flex gap-4 text-white">
<button class="text-sm px-5 py-2 bg-indigo-500 cursor-pointer rounded-full !outline-none hover:brightness-110 active:brightness-90" @click="prev">上一页</button>
<button class="text-sm px-5 py-2 bg-indigo-500 cursor-pointer rounded-full !outline-none hover:brightness-110 active:brightness-90" @click="next">下一页</button>
</div>
</div>
</template>
html, body {
height: 100%;
}