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>