<!-- Use preprocessors via the lang attribute! e.g. <template lang="pug"> -->
<template>
    <div id="app">
        <div class="slides">
            <transition-group tag="div" :name="transitionName" class="img-boxex" >
                <div v-for="(img, idx) of imgs" :key="idx" 
                     class="img-box" v-show="idx === showImg">
                    <img :src="img.src" />
                    <span>{{ idx + 1 }}</span>
                </div>
            </transition-group>
            <div class="btn-group">
                <button class="prev" @click="setShowImg(-1)">◀</button>
                <button class="page" @click="setShowImgTo(num - 1)" 
                        v-for="num in imgs.length" :key="num - 1" >{{ num }}</button>
                <button class="next" @click="setShowImg(1)">▶</button>
            </div>
        </div>
    </div>
</template>

<script>
let timer;
const autoPlayInterval = 5000;

export default {
    data() {
        return {
            transitionName: "right-in",
            showImg: 0,
            imgsCount: 8,
            imgs: [
                { src: "https://picsum.photos/600/400?random=1" },
                { src: "https://picsum.photos/600/400?random=2" },
                { src: "https://picsum.photos/600/400?random=3" },
                { src: "https://picsum.photos/600/400?random=4" },
                { src: "https://picsum.photos/600/400?random=5" }
            ]
        };
    },
    mounted() {
        setInterval(this.setShowImg, autoPlayInterval);
    },
    methods: {
        setShowImg(changeIdx = 1) {
            switch (true) {
                case changeIdx === 1 && this.showImg === this.imgs.length - 1:
                    this.showImg = 0;
                    break;
                case changeIdx === -1 && this.showImg === 0:
                    this.showImg = this.imgs.length - 1;
                    break;
                default:
                    this.showImg = this.showImg + changeIdx;
                    break;
            }
        },
        setShowImgTo(changeIdxTo) {
            this.showImg = changeIdxTo;
        }
    },
    watch: {
        showImg(nIdx, oIdx) {
            this.transitionName = nIdx > oIdx ? "right-in" : "left-in";
        }
    }
};
</script>

<style lang="scss">
#app {
    text-align: center;
    margin: auto;
}
.slides {
    margin: auto;

    .img-boxex {
        position: relative;
        width: 600px;
        height: 400px;
        overflow: hidden;
        margin: 20px auto;
        border: 10px solid white;
        box-shadow: 0px 0px 10px rgb(0 0 0 / 50%);

        .img-box {
            position: absolute;
            
            span {
                position: absolute;
                top: 0;
                left: 0;
                z-index: 2;
                background-color: rgba(0, 0, 0, 0.7);
                padding: 5px 10px;
                color: #fff;
            }
        }
    }
}

// transitionName(Next):'right-in'
.right-in-enter {              // 1-1:enter
    left: 100%;
}
.right-in-enter-active,      // 1-2:enter-active
.right-in-leave-active {     // 2-2:leave-active
    transition: left 0.5s;
}
.right-in-enter-to,          // 1-3:enter-to
.right-in-leave {            // 2-1:leave
    left: 0%;
}
.right-in-leave-to {        // 2-3:leave-to
    left: -100%;
}

// transitionName(Prev):'left-in'
.left-in-enter {            // 1-1:enter
    right: 100%;
}
.left-in-enter-active,      // 1-2:enter-active
.left-in-leave-active {     // 2-2:leave-active
    transition: right 0.5s;
}
.left-in-enter-to,           // 1-3:enter-to
.left-in-leave {            // 2-1:leave
    right: 0%;
}
.left-in-leave-to {         // 2-3:leave-to
    right: -100%;
}
</style>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.