Frontend Development 9 min read

Implementing a Seamless Carousel with Vue: Dynamic Data Switching, Transition Effects, and Auto‑Play Controls

This tutorial explains how to build a seamless carousel in Vue by dynamically switching a data list, using the Transition component for enter/leave animations, adding an auto‑play timer, handling hover pause/resume, and solving visibility‑change flicker with concise CSS and JavaScript code.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing a Seamless Carousel with Vue: Dynamic Data Switching, Transition Effects, and Auto‑Play Controls

The article introduces a common front‑end requirement – a carousel (轮播图) – and shows how to implement it without external UI libraries by writing custom Vue code.

Requirement Overview : Create a seamless carousel that continuously cycles through a list of items, with optional pause on hover and proper handling of page visibility changes.

Implementation Idea : The core concept is to dynamically change the displayed item index in a data array, letting Vue render the current item while the Transition component provides smooth enter and leave animations.

Data List Definition :

const list = ref([
    { name: 1, id: 1 },
    { name: 2, id: 2 },
    { name: 3, id: 3 }
]);

Basic Template Rendering :

<template>
    <div>{{ list[index] }}</div>
</template>
<script setup>
    const index = ref(0);
    const list = ref([{ name: 1, id: 1 }, { name: 2, id: 2 }, { name: 2, id: 2 }]);
</scriptp>

Dynamic List Rendering with v‑for :

<template>
    <div v‑for="(item, i) in list" :key="i">
        <div v‑show="i === selectIndex">Card custom content</div>
    </div>
</template>
<script setup>
    const selectIndex = ref(0);
    const list = ref([
        { name: "卡片1", id: 1 },
        { name: "卡片1", id: 2 },
        { name: "卡片1", id: 2 }
    ]);
    let timer = null;
    const timeFuc = () => {
        timer = setInterval(() => {
            if (selectIndex.value >= list.value.length - 1) {
                selectIndex.value = 0;
            } else {
                selectIndex.value++;
            }
        }, 5000);
    };
    timeFuc();
</scriptp>

Using Vue's Transition Component to animate entry and exit:

<template>
    <div class="main-content">
        <Transition v‑for="(item, i) in list" :key="selectIndex">
            <div class="banner-scroll-wrap" v‑show="i === selectIndex">Card custom content</div>
        </Transition>
    </div>
</template>
<script setup>
    // same data and timer logic as above
</scriptp>

The selectIndex changes dynamically, causing the Transition component to trigger its enter and leave CSS classes.

CSS for Animation (scoped Less):

<style lang="less" scoped>
.main-content { position: relative; height: 100%;
    .banner-scroll-wrap { position: absolute; top:0; bottom:0; left:0; right:0; }
}
.v-enter-from { transform: translateX(100%); opacity: 0; }
.v-enter-active, .v-leave-active { transition: transform 600ms ease-in-out, opacity 600ms ease-in-out; }
.v-enter-to { transform: translateX(0); opacity: 1; }
.v-leave-from { transform: translateX(0); opacity: 1; }
.v-leave-to { transform: translateX(-100%); opacity: 0; }
</style>

Pause and Resume on Hover :

<template>
    <div class="main-content" @mouseenter="stop()" @mouseleave="start()">
</div>
</template>
<script setup>
    const start = () => { if (timer) return; timeFuc(); };
    const stop = () => { clearInterval(timer); timer = null; };
</scriptp>

Handling Visibility Change to avoid flicker after switching browser tabs:

<script setup>
    onMounted(() => {
        document.addEventListener('visibilitychange', () => {
            if (document.visibilityState === 'hidden') { stop(); }
            if (document.visibilityState === 'visible') { start(); }
        });
    });
    onBeforeUnmount(() => stop());
</scriptp>

The visibilitychange event pauses the timer when the page is hidden and resumes it when visible again.

Conclusion : By combining a reactive data list, Vue's Transition component, a simple interval timer, hover controls, and visibility handling, a seamless carousel with smooth left‑to‑right (or top‑to‑bottom by changing translateX to translateY ) can be built without external libraries.

frontendjavascriptVueCSSCarouseltransition
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.