surmon-china / vue-awesome-swiper

šŸ† Swiper component for @vuejs
https://github.surmon.me/vue-awesome-swiper
MIT License
12.82k stars 1.96k forks source link

Don't work properly in a modal plugin #670

Open ShekhSaifuddin007 opened 4 years ago

ShekhSaifuddin007 commented 4 years ago

I'm using this modal plugin vue-js-modal . I'm trying to make an image gallery inside the modal. outside this modal, it's work I aspected but inside modal, it shows me the error and does not work properly Capture

My code image gallery

<template>
     <modal name="quick-view" width="90%" height="auto" :maxWidth="1000" :maxHeight="600" :adaptive="true">
          <div class="modal-content-wrapper">
              <button @click="hide" class="modal-close">Close me</button>

              <div class="product-details">
                 <div class="product-carousel">
                    <!-- swiper1 -->
                    <swiper class="swiper gallery-top" :options="swiperOptionTop" ref="swiperTop">
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614568/pickbazar/grocery/GreenLimes_jrodle.jpg" alt="">
                        </swiper-slide>
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614568/pickbazar/grocery/Yellow_Limes_y0lbyo.jpg" alt="">
                        </swiper-slide>
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614569/pickbazar/grocery/RedCherries_zylnoo.jpg" alt="">
                        </swiper-slide>
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614568/pickbazar/grocery/CelerySticks_ulljfz.jpg" alt="">
                        </swiper-slide>
                    </swiper>

                    <!-- swiper2 Thumbs -->
                    <swiper class="swiper gallery-thumbs" :options="swiperOptionThumbs" ref="swiperThumbs">
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614568/pickbazar/grocery/GreenLimes_jrodle.jpg" alt="">
                        </swiper-slide>
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614568/pickbazar/grocery/Yellow_Limes_y0lbyo.jpg" alt="">
                        </swiper-slide>
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614569/pickbazar/grocery/RedCherries_zylnoo.jpg" alt="">
                        </swiper-slide>
                        <swiper-slide>
                            <img src="https://res.cloudinary.com/redq-inc/image/upload/c_fit,q_auto:best,w_300/v1589614568/pickbazar/grocery/CelerySticks_ulljfz.jpg" alt="">
                        </swiper-slide>
                    </swiper>
                </div>
                <div class="p-10">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aspernatur at, dignissimos dolorum enim ex expedita fuga harum.</div>
            </div>
        </div>
    </modal>
</template>

<script>
    import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
    import 'swiper/css/swiper.css'

    export default {
    name: "Products",
    components : {
        Swiper, SwiperSlide
    },
    data() {
        return {
            swiperOptionTop: {
                loop: true,
                loopedSlides: 5, // looped slides should be the same
                spaceBetween: 10,
            },
            swiperOptionThumbs: {
                loop: true,
                loopedSlides: 5, // looped slides should be the same
                spaceBetween: 10,
                centeredSlides: true,
                slidesPerView: 'auto',
                touchRatio: 0.2,
                slideToClickedSlide: true
            }
        }
    },
    mounted() {
        this.$nextTick(() => {
            const swiperTop = this.$refs.swiperTop.$swiper
            const swiperThumbs = this.$refs.swiperThumbs.$swiper
            swiperTop.controller.control = swiperThumbs
            swiperThumbs.controller.control = swiperTop
        })
    },

    methods : {
        show () {
            this.$modal.show('quick-view');
        },
        hide () {
            this.$modal.hide('quick-view');
        }
      }
    }
</script>
khemmachattk commented 4 years ago

try this

 methods: {
    show () {
      this.$modal.show('quick-view');

      this.$nextTick(() => {
        const swiperTop = this.$refs.swiperTop.$swiper
        const swiperThumbs = this.$refs.swiperThumbs.$swiper
        swiperTop.controller.control = swiperThumbs
        swiperThumbs.controller.control = swiperTop
      })
    },
  }
ShekhSaifuddin007 commented 4 years ago

Same error show after open modal šŸ˜’

ShekhSaifuddin007 commented 4 years ago

I have created a reusable modal like my own and I have seen the same problem there, šŸ˜’ help me, anybody, plz..

ShekhSaifuddin007 commented 4 years ago

@surmon-china plz. help me

broadcoder commented 4 years ago

The error does not state, that there is no $swiper, the error states, that it can't read $swiper from something, that is undefined. So your issue seem to be, that the $refs does not contain your elements. Maybe that helps you, to look further, why vue does not have your $refs available in that situation.

I think the modal component might use a v-if to show or hide the element, and when the whole modal is not shown, it is removed from the DOM and thus there is no way $refs are available. You either check if the ref is present and execute your code then or (if that is possible) you could use v-show instead of v-if to hide the modal.

So in general it seems to work: https://jsfiddle.net/3mbkfrnj/