I'm using vue-flickity for a carousel. There's a <flickity />
component (the carousel), a <p>
tag with data {{ selectedIndex }}
, and a button which gets the current slide number from flickity
, and updates selectedIndex
.
How can I automatically update selectedIndex
with the current slide index when a user scrolls left or right (i.e. calls Next/Previous methods)? I'm struggling to "hook into" those methods of the module.
I can define a method Next()
and bind that to a button, but it doesn't update when a user scrolls.
EDIT: I've managed to hook into on.change
(using mounted
). console.log
shows me the correct selectedInde
now, but this isn't reacting down to where it says "You are at Slide number {{ selectedIndex }}"
<template>
<div>
<flickity ref="flickity" :options="flickityOptions">
<div class="carousel-cell">1</div>
<div class="carousel-cell">2</div>
<div class="carousel-cell">3</div>
<div class="carousel-cell">4</div>
<div class="carousel-cell">5</div>
</flickity>
<p>You are at Slide number {{ selectedIndex }}</p>
<button @click="manualUpdate()">Update</button>
</div>
</template>
<script>
import Flickity from 'vue-flickity'
export default {
components: {
Flickity
},
data() {
return {
flickityOptions: {
initialIndex: 0,
prevNextButtons: false,
pageDots: false,
wrapAround: true
},
selectedIndex: 0
}
},
methods: {
manualUpdate() {
this.selectedIndex = this.$refs.flickity.selectedIndex();
console.log(this.selectedIndex)
},
},
mounted() {
this.$refs.flickity.on('change', function (event) {
this.selectedIndex = event
console.log(this.selectedIndex)
})
}
}
</script>
<style>
/* external css: flickity.css */
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.carousel-cell {
width: 80%;
min-height: 50vh;
max-height: 80vh;
object-fit: contain;
margin-right: 10px;
}
</style>
As explain on this Github issue, you need to bind the listener on the init
event.
The end result looks like this:
<template>
<div>
<flickity ref="flickity" :options="flickityOptions" @init="onInit">
<div class="carousel-cell">1</div>
<div class="carousel-cell">2</div>
<div class="carousel-cell">3</div>
<div class="carousel-cell">4</div>
<div class="carousel-cell">5</div>
</flickity>
<p>You are at Slide number {{ selectedIndex }}</p>
<button @click="goToPrevious">Previous</button>
<button @click="goToNext">Next</button>
</div>
</template>
<script>
import Flickity from 'vue-flickity'
export default {
components: {
Flickity,
},
data() {
return {
flickityOptions: {
initialIndex: 0,
prevNextButtons: false,
pageDots: false,
wrapAround: true,
},
selectedIndex: 0,
}
},
methods: {
goToNext() {
this.$refs.flickity.next()
},
goToPrevious() {
this.$refs.flickity.previous()
},
onInit() {
this.$refs.flickity.on('change', (event) => {
this.selectedIndex = event
console.log('current index', event)
})
},
},
}
</script>
<style>
/* external css: flickity.css */
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.carousel-cell {
width: 80%;
min-height: 50vh;
max-height: 80vh;
object-fit: contain;
margin-right: 10px;
}
</style>
There was indeed no other event, which is super strange and I took the libery to write previous/next buttons rather than keep something manual but you could compute and offset (did not found any method for a direct setter).