Me gustaría alternar una clase 'activa' en una lista de elementos:
<div ref="gallery" class="slider"> <div class="slide active"> <div class="slide"> <div class="slide"> </div>Usando Vue y Vanilla JS
Slider() { const slider = document.querySelectorAll('.slider') for (const slide of slider) { setInterval(function () { const current = slide.querySelector('.active') current.classList.remove('active') const next = current.nextElementSibling || slide.firstElementChild next.classList.add('active') }, 5000) } }Si bien el código anterior funciona , creo que no es tan limpio como podría ser.
Además, y principalmente, si apunto el control deslizante usando una referencia Vue como:
const slider = this.$refs.gallerydeja de funcionar
La respuesta de tony19 me llevó a reducir aún más el código usando Nuxt:
export default { data() { return { activeIndex: 0, slides: [ { id: 1, text: 'Slide 1' }, { id: 2, text: 'Slide 2' }, { id: 3, text: 'Slide 3' }, ] } }, mounted() { this.Slider() }, methods: { Slider() { setInterval(() => { this.activeIndex = (this.activeIndex + 1) % this.slides.length }, 3000) } } } <template> <div class="slider"> <div v-for="(slide, index) in slides" :key="slide.id" :class="['slide', { active: index === activeIndex }]"> {{ slide.text }} </div> </div> </template>Puede usar un enlace de clase que establezca la class en active según el índice activo:
Declare una propiedad activeIndex para contener el índice activo.
En el gancho mounted , usa setInterval() con una devolución de llamada que incrementa activeIndex . Rastree la ID del temporizador de setInterval() para que podamos detener el temporizador más tarde.
En el gancho unmounted , detenga el temporizador de intervalos con clearInterval() en la ID del temporizador.
Utilice la sintaxis de objetos para vinculaciones de clases para vincular una clase active solo cuando activeIndex coincida con el índice de la diapositiva de v-for .
<script setup> import { ref, onMounted, onUnmounted } from 'vue' let timerId = -1 1️⃣ const activeIndex = ref(0) const slides = ref([ { id: 1, text: 'Slide 1' }, { id: 2, text: 'Slide 2' }, { id: 3, text: 'Slide 3' }, ]) 2️⃣ onMounted(() => { timerId = setInterval(() => { activeIndex.value = (activeIndex.value + 1) % slides.value.length }, 3000) }) 3️⃣ onUnmounted(() => { clearInterval(timerId) }) </script> <template> <div ref="gallery" class="slider"> <div v-for="(slide, index) in slides" :key="slide.id" class="slide" 4️⃣ :class="{ active: index === activeIndex }"> {{ slide.text }} </div> </div> </template>Hice esta demostración en formato vue.js según su solicitud. Eche un vistazo y vea si esto es lo que realmente quiere lograr.
demostración:
new Vue({ el: '#app', data: { slideData: [{ name: 'Slide 1', isActive: true }, { name: 'Slide 2', isActive: false }, { name: 'Slide 3', isActive: false }] }, mounted() { this.slideData.forEach((obj) => { setInterval(() => { obj.isActive = !obj.isActive; }, 3000); }); } }) .active { color: white; background-color: green; } <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <div v-for="(slider, index) in slideData" class="slide" :class="{ active: slider.isActive }"> {{ slider.name}} </div> </div>