0

i have created gallery component in vue, which has lightbox with following code

<div id="lightbox" class="modal" v-if="photo !== null" v-show="showModal" @click.self="closeModal">
    <div class="modal-content">
        <div class="slide">
            <div class="slide-number" v-if="cardsView">
                {{ photos.findIndex((p) => p.id == photo.id) + 1 }} / {{ photos.length }}
            </div>
            <div class="slide-number" v-if="!cardsView">
                {{ csSortedPhotos.findIndex((p) => p.id == photo.id) + 1 }} / {{ csSortedPhotos.length }}
            </div>
            <!-- <img :src="photo.s3Path" alt="Photo has not been loaded."
                class="modal-img"
                v-touch:swipe.right="prevSlide"
                v-touch:swipe.left="nextSlide"
            > -->
            <img v-for="ph in photos" :src="ph.s3Path"
                v-show="photo.id == ph.id" alt="Photo has not been loaded."
                class="modal-img"
                v-touch:swipe.right="prevSlide"
                v-touch:swipe.left="nextSlide"
            >
        </div>
.
.
.

previously I used the commented out part to display photo in modal

<img :src="photo.s3Path" alt="Photo has not been loaded."
    class="modal-img"
    v-touch:swipe.right="prevSlide" v-touch:swipe.left="nextSlide"
>

however, i had to change it to this, because client wanted to be able to use nextSlide function with zero delay

<img v-for="ph in photos" :src="ph.s3Path" v-show="photo.id == ph.id" alt="Photo has not been loaded."
    class="modal-img"
    v-touch:swipe.right="prevSlide" v-touch:swipe.left="nextSlide"
>

This works much better and photos are iterable quickly. However, the next catch is that I assume vue considers this element unimportant (since v-show on modal is false by default) and starts loading all the images after the modal has been opened for first time. This results in 1-4 seconds of wait after you click on the first photo to open.

My question is - do I assume correctly how vue works in this matter? And can I somehow tell vue, to load these elements right away with no delay?

narrei
  • 516
  • 2
  • 6
  • 19
  • See if this helps: https://stackoverflow.com/questions/52859322/adding-a-default-image-to-my-img-vue – danh Aug 17 '21 at 20:59
  • 1
    Vue does not load anything. Vue just generates HTML (directly to the DOM). The browser is rendering and downloading what is needed. It is not possible to answer your question without knowing CSS you are using. Seems your gallery component is content of some modal (`class="modal-content"`). Is this modal used with `v-if` or `v-show`? You can find some more info here - [Does “display:none” prevent an image from loading?](https://stackoverflow.com/q/12158540/381282) – Michal Levý Aug 18 '21 at 06:02

1 Answers1

0

thank's to Michal Levý's comment I went looking through dev console to see what is actually happenig.

I edited the question to add the first line to the block of code with this important info

<div id="lightbox"
    class="modal"
    v-if="photo !== null"
    v-show="showModal"
    @click.self="closeModal"
>

while developing my gallery I only had v-show="showModal condition on this div, but later as I added body, it would throw error, because i would try to access attributes of null (photo.id for example), so i added v-if="photo !== null" which works differently from v-show. v-show sets display: none; and v-if does not render the element at all, so of course the DOM does not load the image.

therefore, in my axios then block i added a line after setting the array of photos

this.photos = response.data
this.photo = this.photos[0]

to set selected photo to the first array element, even if it is still not displayed. this line puts modal in the DOM and images load right away.

narrei
  • 516
  • 2
  • 6
  • 19