I’m making a custom image slider using vuex, I want to apply a specific class to the dots used for navigating the sliders, so if the dot is active it will be applied a dotActive class. I want to use activeSlider variable for this
This is the slider component:
<template> <section class="slider_maincontainer"> <transition-group name="slider-fade"> <div class="slider_item" v-show="activeSlider===1" style="background-color:red;"> <!--slider content--> </div> <div class="slider_item" v-show="activeSlider===2" style="background-color:blue;"> <!--slider varied content--> </div> <div class="slider_item" v-show="activeSlider===3" style="background-color:green;"> <!--another slider--> </div> </transition-group> <button class="slider_buttom_prev" @click="prevSlider()"> <i class="slider_buttom_icon fas fa-angle-left"></i> </button> <button class="slider_buttom_next" @click="nextSlider()"> <i class="slider_buttom_icon fas fa-angle-right"></i> </button> <div class="slider_dots_container"> <!--how to apply custom class to this dot depending of activeIndex <span class="slider_dots_dot" v-for="slider in slidersCount" :key="slider" @click="goToSlider(slider)"></span> </div> </section> </template> <!--SCRIPTS--> <script> import { mapState, mapActions } from 'vuex' export default { name: 'MainSlider', computed:{ ...mapState('MainSlider', ['activeSlider', 'slidersCount']), }, mounted() { console.log(this.$options.name+' component successfully mounted'); this.startSlider(); }, methods:{ ...mapActions('MainSlider', ['nextSlider', 'prevSlider']), } }; </script>
And my Slider Store:
//STATE const state = { slidersCount: 3, sliderInterval: 3000, activeSlider: 1, } //GETTERS const getters = { } //ACTIONS const actions = { prevSlider ({ commit, state }) { if(state.activeSlider == 1){ commit( 'TO_LAST_SLIDER' ); } else{ commit( 'PREV_SLIDER' ); } }, nextSlider ({ commit, state }) { if(state.activeSlider == state.slidersCount){ commit( 'TO_FIRST_SLIDER' ); } else{ commit( 'NEXT_SLIDER' ); } }, goToSlider ({ commit, sliderIndex }) { commit('GO_TO_SLIDER', sliderIndex) }, } //MUTATIONS const mutations = { PREV_SLIDER (state) { state.activeSlider--; }, NEXT_SLIDER (state) { state.activeSlider++; }, GO_TO_SLIDER (state, sliderIndex) { state.activeSlider = sliderIndex; }, TO_FIRST_SLIDER (state) { state.activeSlider = 1; }, TO_LAST_SLIDER (state) { state.activeSlider = state.slidersCount; }, } export default { namespaced: true, state, getters, actions, mutations }
I know this could be made easier if each dom slider where associated with an object along with using a v-for but afaik I can’t do that with raw dom element, I’m not getting the slider images from backend or anything.
Advertisement
Answer
You could use a class binding that activates the dotActive
class for a specific span
only when activeSlider
matches the span
‘s slider
index:
<span v-for="slider in sliderCount" :class="{ dotActive: slider === activeSlider }">
new Vue({ el: '#app', data: () => ({ activeSlider: 1, sliderCount: 3, }), methods: { slide(diff) { let slider = (this.activeSlider + diff) % (this.sliderCount + 1); // wrap around if (slider === 0) { slider = (diff > 0) ? 1 : this.sliderCount; } this.activeSlider = slider; }, } })
#app { display: flex; justify-content: center; flex-direction: column; align-items: center; } .button_container { margin: 20px; } .slider_dots_container { width: 5%; display: flex; justify-content: space-around; } .slider_dots_dot { border: solid 2px lightgray; border-radius: 50%; height: 1px; } .dotActive { border-color: black; }
<script src="https://unpkg.com/vue@2.5.17"></script> <div id="app"> <div class="button_container"> <button @click="slide(-1)">Prev</button> <button @click="slide(1)">Next</button> {{activeSlider}} </div> <div class="slider_dots_container"> <span v-for="slider in sliderCount" :key="slider" class="slider_dots_dot" :class="{ dotActive: slider === activeSlider }"> </span> </div> </div>