Vue-carousel: When page is opened image in vue-carousel is not visible. Need to click.

Created on 31 May 2019  路  15Comments  路  Source: SSENSE/vue-carousel

Bug Report

Hello,
Working with Laravel 5.7 / Vuejs 2.6 / Bootstrap 4.3 app I use "vue-carousel": "^0.18.0"
I have a problem that defing carousel with images at page opening the page is not visible at all.
But if to click on the empty image space then image is visible and carousel works ok.
in vue file :
```

                <div class="pull-left" style="max-width: 350px;">
                    <carousel
                            v-show="hostelImages.length"
                            :centerMode="false"
                            :perPage="1"
                            :navigationEnabled="true"
                            paginationColor="#7e7e7e"
                            paginationPosition="bottom"
                            class="m-4"
                            zIndex= "100 !important"
                    >
                        <slide v-for="nextHostelImage, index in hostelImages" :key="nextHostelImage.id">
                            <img :src="nextHostelImage.filenameData.image_url" :alt="nextHostelImage.filename" style="width:320px; height : auto; ">
                            <p class="description-text pl-5 pr-5">
                                {{ nextHostelImage.info }}
                            </p>
                        </slide>
                    </carousel>

                    <a class="a_link" href="/images/emptyImg.png" v-show="!hostelImages.length">
                        <!--{{  "?dt=".time()  }}-->
                        <img class="single_vote_image_left_aligned" src="/images/emptyImg.png" alt="alt text">
                    </a>
                </div>


                <p class="card-text mt-3 description-text" v-html="hostelRow.descr"></p>
                ...

All 15 comments

Searching for a decision I found vue-focus directive. I installed it to my app and checking it on
simple text input I see that it works ok.
I tried to use it in carousel component as :

                        <carousel
                                v-show="hostelImages.length"
                                :centerMode="false"
                                :perPage="1"
                                :navigationEnabled="true"
                                paginationColor="#7e7e7e"
                                paginationPosition="bottom"
                                class="m-4"
                                zIndex= "100 !important"
                        >
                            <slide v-for="nextHostelImage, index in hostelImages" :key="nextHostelImage.id">
                                <img
                                        :src="nextHostelImage.filenameData.image_url"
                                        :alt="nextHostelImage.filename"
                                        style="width:320px; height : auto; "
                                        v-focus.lazy="true"
                                >
                                <p class="description-text pl-5 pr-5">
                                    {{ nextHostelImage.info }}
                                </p>
                            </slide>
                        </carousel>


OR

                        <carousel
                                v-show="hostelImages.length"
                                :centerMode="false"
                                :perPage="1"
                                :navigationEnabled="true"
                                paginationColor="#7e7e7e"
                                paginationPosition="bottom"
                                class="m-4"
                                zIndex= "100 !important"
                                v-focus.lazy="true"
                        >
                            <slide v-for="nextHostelImage, index in hostelImages" :key="nextHostelImage.id">
                                <img
                                        :src="nextHostelImage.filenameData.image_url"
                                        :alt="nextHostelImage.filename"
                                        style="width:320px; height : auto; "
                                >
                                <p class="description-text pl-5 pr-5">
                                    {{ nextHostelImage.info }}
                                </p>
                            </slide>
                        </carousel>

But in both cases I do not see images on page opened.

2) If there is a way to simulate click of a mouse on carousel's image?

3) Testing in browser I noticed that when I change device in browse I see that my carousel's image becomes visible.
Can that be decision for my problem ?

@PetroGromovo I have the exact same issue.. Did you find another solution so you did'nt have to simulate a maouse click?

Found another one who had the same problem:
try: style="visibility: visible; flex-basis: 522px;"

or

.VueCarousel-slide {
visibility: visible;
flex-basis: 100%;
width: 100%;
}

I have a same problem, and find some trick.
I think the problem is, window doesn't fire resize event when image loaded.

Try :

var resizeEvent = window.document.createEvent('UIEvents');
resizeEvent.initUIEvent('resize', true, false, window, 0);
window.dispatchEvent(resizeEvent);

inside of mounted hook function.

I've found a hacky workaround for this but I 100% think this issue needs to be fixed properly.
My workaround is to call the $forceUpdate() in the mounted hook on a timeout.
The timeout should be longer than the time it takes for all of the carousel's content to load.

mounted() {
    setTimeout(() => {
      this.$forceUpdate()
    }, 4000)
}

This will force the component to re-render.
NOTE
This does not just re-render the carousel, it re-renders the component in which the vue-carousel is being used.
Again, this is not a permanent workaround and I recommend that it is not used in a production environment.

@damienmcd can't you just put a ref on carousel and call $forceUpdate in the carousel itself?

Also, talking about "magic numbers" with usage of setTimeout: in case we are dealing with images (img tags to be sure) you can apply this kind of stuff using load event, so carousel only updates when images are really loaded by the browser.

Hi @lennoximus.
Thanks for your suggestion, you're correct that using a ref on the carousel and just calling the forceUpdate on that is a better way to handle the re-render of the carousel. I don't know how I didn't think of that. Maybe it was the Friday afternoon brain switching off!

With regard to using the load event, this is not called if the images are loaded from the cache so I may have to create the images with a new Image() and bind a load event listener to them.

Anyway, hopefully the actual issue can be fixed by the vue-carousel devs soon so we don't have to be hacking around with alternatives.

A quick update on this. Adding a ref to the vue-carousel and calling $forceUpdate() on that does not resolve this issue.
It works on Chrome sometimes but not on IE11, which I need it to work on.
I'm still looking for a fix for this and I'll post my findings here if I manage to get it working.

Hi all. I've had the same problem and came up with a "hacky" solution using the imagesLoaded directive from here.

Basically you use the directive to detect if the images have loaded. If they did, use the $forceUpdate function in the imagesLoaded callback to update the carousel accordingly.

Hope this helps!

<template>
    <carousel v-images-loaded="imageLoaded" ref="carousel">
        <slide v-for="(photo, index) in photos" :key="index">
           <img :src="photo.file"/>
        </slide>
    </carousel>
</template>

<script>
    export default {
        methods: {
            imageLoaded() {
                console.log('force load');
                this.$refs.carousel.$forceUpdate()
            },
        },
    }
<script>

Hi all! My solution without $forceUpdate(). Use vue-carousel computeCarouselWidth() method.

<carousel
  :perPage="1"
  :paginationEnable="true"
  paginationColor="#b3b3b3"
  paginationActiveColor="#494ce8"
  ref="carousel"
>
  <slide v-for="(slide, index) in product.gallery" :key="index">
    <img :src="slide.img" :alt="slide.name" />
  </slide>
</carousel>
mounted () {
    setTimeout(this.$refs.carousel.computeCarouselWidth, 300)
}

@kubmin Thanks, you save me

@kubmin Thanks, you save me

good luck)

@JonikUl Thank you so much! This simple solution worked for me.

@JonikUl Thank you so much! This simple solution worked for me.

TU, glad that helped

With just this class my problem was solved:

.VueCarousel {
  width: 100%;
  height: 100%;
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

hdodov picture hdodov  路  5Comments

gomezmark picture gomezmark  路  5Comments

valeriy-efimov picture valeriy-efimov  路  5Comments

bepi-roggiuzza picture bepi-roggiuzza  路  4Comments

power-cut picture power-cut  路  5Comments