vue-awesome-swiper icon indicating copy to clipboard operation
vue-awesome-swiper copied to clipboard

Swipper contoller thumb in loop ( async )

Open dudenk opened this issue 7 years ago • 22 comments

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.

dudenk avatar Feb 17 '18 09:02 dudenk

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!

sebastianjung avatar Apr 24 '18 15:04 sebastianjung

@sebbler1337 have you an example? :D

GiboMac avatar May 14 '18 13:05 GiboMac

im on vacation right now and do not have any codeing stuff with me so unfortunately no.

sebastianjung avatar May 15 '18 16:05 sebastianjung

same issue !!!

bocanhcam avatar Jan 29 '19 07:01 bocanhcam

For anyone looking at this example wraps something like @sebastianjung suggested in the mounted() method.

GarethSomers avatar May 03 '19 11:05 GarethSomers

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
    }
  },

carmineprince avatar Jun 26 '19 09:06 carmineprince

same issue !!!

horshechnyk avatar Nov 15 '19 09:11 horshechnyk

Any solution how to fix this ?

saices avatar Mar 26 '20 18:03 saices

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

thomaslecoeur avatar Jul 31 '20 22:07 thomaslecoeur

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..

ErwinCode avatar Oct 30 '20 12:10 ErwinCode

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.

voltane avatar Oct 30 '20 17:10 voltane

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
},

awkoy avatar Dec 27 '20 15:12 awkoy

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

AndrewBogdanovTSS avatar Jan 06 '21 20:01 AndrewBogdanovTSS

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 avatar Jun 28 '21 14:06 elenafrontend

@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 avatar Jul 09 '21 23:07 senecaso

@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

elenafrontend avatar Jul 14 '21 14:07 elenafrontend

@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 avatar Jul 14 '21 14:07 elenafrontend

@elenafrontend thank you, it worked for me!

"swiper": "^5.3.7",
"vue-awesome-swiper": "^4.1.1"

varave avatar Sep 22 '21 17:09 varave

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

fisherspoons avatar Oct 21 '21 14:10 fisherspoons

I figured out the problem is that you do not import all needed modules specially Controller from Swiper.

aliwesome avatar Nov 14 '21 14:11 aliwesome

@fisherspoons that's because you should log it like this:

mounted () {
    this.$nextTick(() => {
       console.log(this.$refs.swiperTop.$swiper)
    })
  }

aliwesome avatar Nov 14 '21 14:11 aliwesome

{
  "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>

kubyshkin1994 avatar Jan 26 '23 17:01 kubyshkin1994