surmon-china / vue-awesome-swiper

🏆 Swiper component for @vuejs
https://github.surmon.me/vue-awesome-swiper
MIT License
12.81k stars 1.96k forks source link

Swipper contoller thumb in loop ( async ) #272

Open dudenk opened 6 years ago

dudenk commented 6 years ago

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.

sebastianjung commented 6 years ago

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!

GiboMac commented 6 years ago

@sebbler1337 have you an example? :D

sebastianjung commented 6 years ago

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

bocanhcam commented 5 years ago

same issue !!!

GarethSomers commented 5 years ago

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

carmineprince commented 5 years ago
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
    }
  },
horshechnyk commented 4 years ago

same issue !!!

saices commented 4 years ago

Any solution how to fix this ?

thomaslecoeur commented 4 years ago

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

ErwinCode commented 3 years ago

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

voltane commented 3 years ago

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:

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.

awkoy commented 3 years ago

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

AndrewBogdanovTSS commented 3 years ago

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

elenafrontend commented 3 years ago

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() }

senecaso commented 3 years ago

@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",
elenafrontend commented 3 years ago

@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 commented 3 years ago

@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

varave commented 3 years ago

@elenafrontend thank you, it worked for me!

"swiper": "^5.3.7",
"vue-awesome-swiper": "^4.1.1"
fisherspoons commented 3 years ago

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

aliwesome commented 2 years ago

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

aliwesome commented 2 years ago

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

mounted () {
    this.$nextTick(() => {
       console.log(this.$refs.swiperTop.$swiper)
    })
  }
kubyshkin1994 commented 1 year ago
{
  "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>