vue-awesome-swiper
vue-awesome-swiper copied to clipboard
Swipper contoller thumb in loop ( async )
i have template
<swiper :options="swiperOptionTop" class="gallery-top" ref="swiperTop">
<swiper-slide v-for="(slide,index) in swiperSlides" :key="index" :class="'slide-' + slide.id">
<img alt="" :src="slide.img">
</swiper-slide>
<div class="swiper-button-next swiper-button-white" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-white" slot="button-prev"></div>
</swiper>
<!-- swiper2 Thumbs -->
<swiper :options="swiperOptionThumbs" class="gallery-thumbs" ref="swiperThumbs">
<swiper-slide v-for="(slide,index) in swiperSlides" :key="index" :class="'slide-' + slide.id">
<img alt="" :src="slide.img">
</swiper-slide>
</swiper>
and script
data () {
return {
swiperOptionTop: {
spaceBetween: 10,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}
},
swiperOptionThumbs: {
spaceBetween: 10,
centeredSlides: false,
slidesPerView: 'auto',
touchRatio: 0.2,
slideToClickedSlide: true
},
swiperSlides: [
{id: 1, img: '/static/images/products/product_01.jpg'},
{id: 2, img: '/static/images/products/product_02.jpg'},
{id: 3, img: '/static/images/products/product_03.jpg'}
],
swiperSlidesThumb: [
{id: 1, img: '/static/images/products/product_01.jpg'},
{id: 2, img: '/static/images/products/product_02.jpg'},
{id: 3, img: '/static/images/products/product_03.jpg'}
]
}
},
mounted () {
this.$nextTick(() => {
const swiperTop = this.$refs.swiperTop.swiper
const swiperThumbs = this.$refs.swiperThumbs.swiper
swiperTop.controller.control = swiperThumbs
swiperThumbs.controller.control = swiperTop
})
}
the thumbnail not controller main slider.
Lol i was looking for a solution for making synced sliders work and your post actually helped me. So thanks for that!
This worked for me (using typescript so you may not need "as any"):
const leftSlider = this.$refs.leftSlider as any;
const rightSlider = this.$refs.rightSlider as any;
leftSlider.swiper.controller.control = rightSlider.swiper;
rightSlider.swiper.controller.control = leftSlider.swiper;
Hope this helps!
@sebbler1337 have you an example? :D
im on vacation right now and do not have any codeing stuff with me so unfortunately no.
same issue !!!
For anyone looking at this example wraps something like @sebastianjung suggested in the mounted()
method.
updated () {
if (this.isInit === 1) {
this.$nextTick(() => {
const swiperTop = this.$refs.swiperTop.swiper
const swiperThumbs = this.$refs.swiperThumbs.swiper
swiperTop.controller.control = swiperThumbs
swiperThumbs.controller.control = swiperTop
})
this.isInit = 0
}
},
same issue !!!
Any solution how to fix this ?
A bit late, but the solution for you guys is here 👍
To access the Swiper instance, donc forget the $
before swiper
: this.$refs.swiperTop.$swiper
instead of this.$refs.swiperTop.swiper
I'm still getting this TypeError:
TypeError: Cannot set property 'control' of undefined.
With $
before swiper
I can log the instance but I can't find the controller..
I can confirm its not working. controller
does not exist on $swiper
. Adding it manually also does not work.
Trying fallback to solution from swiper below v4, and using params.control
also does not work.
I'm using latest versions:
- "vue-awesome-swiper": "4.1.1"
- "swiper": "6.3.4"
My temporary workaround is to use slideChange
event on thumbnail instance like this:
@slideChange="onThumbnailChange"
where onThumbnailChange
function looks like this:
onThumbnailChange(val) {
this.$refs.swiperTop.$swiper.slideTo(val.activeIndex)
},
I'm using activeIndex
instead of realIndex
because in my case i set loop
parameter to true (for reason why, check note here: https://swiperjs.com/api/#events and search for mySwiper.activeIndex).
In my case it works fine. Hope it helps till proper fix.
Hi everyone! I found a solution:
computed: {
swiperTop() {
return this.$refs.swiperTop.$swiper;
},
swiperThumbs() {
return this.$refs.swiperThumbs.$swiper;
},
},
mounted() {
this.swiperTop.controller.control = this.swiperThumbs
this.swiperThumbs.controller.control = this.swiperTop
},
Using mounted is not ideal for this. You should first initialize thumbs swiper, subscribe to it's init event which will give you access to a swiper instance which you should pass to a second swiper you want to control
it works for me
computed: { gallery () { return this.$refs.gallerySlider.$swiper }, thumbs () { return this.$refs.thumbsSlider.$swiper } },
mounted () { this.gallery.thumbs.swiper = this.thumbs this.gallery.thumbs.init() }
@elenafrontend which version of Swiper were you using? I'm trying what you did using the latest versions, and this.gallery.thumbs
is always undefined. I'm probably just missing something
"swiper": "^6.7.5",
"vue-awesome-swiper": "^4.1.1",
@senecaso I was using: "swiper": "^6.7.1", "vue-awesome-swiper": "^4.1.1"
also you can read this last documentation, where you can find examples : https://github.com/nomunomu0504/vue-awesome-swiper there are two ways to init swiper, which one were you using? https://github.com/nomunomu0504/vue-awesome-swiper#difference-with-usage
@senecaso if it was directive you can only add this:
mounted () { this.modalSlider.thumbs.swiper = this.modalThumbs this.modalSlider.thumbs.init() },
where .modal-gallery(v-swiper:modalSlider="modalGalleryOption") - main slider .modal-thumbs(v-swiper:modalThumbs="modalThumbsOption") - previews slider
@elenafrontend thank you, it worked for me!
"swiper": "^5.3.7",
"vue-awesome-swiper": "^4.1.1"
Hi, I had same problem "swiper": "^5.4.5", "vue-awesome-swiper": "^4.1.1",
return this.$refs.swiperTop.$swiper in computed always return undefined
I figured out the problem is that you do not import all needed modules specially Controller
from Swiper
.
@fisherspoons that's because you should log it like this:
mounted () {
this.$nextTick(() => {
console.log(this.$refs.swiperTop.$swiper)
})
}
{
"dependencies": {
"swiper": "5.x",
"vue-awesome-swiper": "^4.1.1",
}
}
<template>
<div>
<swiper
ref="image"
:options="imgOptions"
:cleanup-styles-on-destroy="false"
>
<swiper-slide
v-for="item in slides"
:key="item.id"
>
<img
v-if="item.image && item.image.src"
:src="item.image.src"
:alt="item.image.alt"
>
</swiper-slide>
</swiper>
<swiper
ref="description"
:options="textOptions"
:cleanup-styles-on-destroy="false"
>
<swiper-slide
v-for="item in slides"
:key="item.id"
>
<p>{{ item.description }}</p>
</swiper-slide>
</swiper>
</div>
</template>
<script>
export default {
props: {
slides: Array,
},
data() {
return {
imgOptions: {
loop: false,
slidesPerView: 1,
watchOverflow: true,
effect: 'fade',
fadeEffect: {
crossFade: true,
},
},
textOptions: {
loop: false,
slidesPerView: 1,
watchOverflow: true,
autoHeight: true,
autoplay: {
delay: 3000,
disableOnInteraction: false,
},
},
}
},
computed: {
swiperImg() {
return this.$refs.image.$swiper;
},
swiperDescr() {
return this.$refs.description.$swiper;
},
},
mounted() {
this.swiperImg.controller.control = this.swiperDescr;
this.swiperDescr.controller.control = this.swiperImg;
},
}
</script>