I have code that fetches a list of images as an object like
[
{ src: '/path/to/img.jpg', loaded: false },
...
]
and template that then renders them as HTML like:
<div
v-for="image in alltheimages"
:key="image.id" >
<transition name="fade" appear>
<img
:src="image.src"
v-show="image.loaded"
@load="image.loaded = true"
/>
</transition>
</div>
This works well when first loading the page; the images fade in as soon as they're loaded.
However there's a problem when the image is already loaded in cache because then the @load
never fires on the new <img>
element. In these situations I can check the DOM img tag's .complete
property, but how can I do that in VueJS?
I've tried v-show="this.complete || image.loaded"
but this
just points to window
. I thought I could use a method call and pass a reference to the element which initiated the call, but I can't find out how to do that either.
I realise I could load all the images separately with new Image()
, bind a listenter to the load
event before I provide src
and from there update the data to say the thing is loaded, but that a whole lotta code and objects - be much nicer to be able to use the DOM elements Vue creates.
Approach: We are going to use an event in <img> to check whether an image is loaded or not in VueJS, the event we are going to use is: @load: The @load event gets triggered when the image is loaded and it gets executed.
To display an image with the img tag in vue, you can use v-bind:src directive, or :src . Or :src for short. Remember that :src expects a JavaScript expression, so if you want to use a string literal in :src you need to wrap the string in quotes.
Aug 29, 2022. You can dynamically control the image an <img> tag displays using the v-bind:src , or :src for short, binding. This allows you to insert JavaScript in the attribute field.
I didn't have any luck with this method, nor with vue-images-loaded but vue-onload worked like a charm.
In main.js add:
import OnLoad from 'vue-onload'
Vue.use(OnLoad);
and on the images you are loading:
<img
class="gallery__image"
v-onload="[image src]"
/>
then just add whatever css animation you want to to occur in your stylesheet:
/*loaded state*/
.gallery__image {
opacity: 1;
transition: opacity 1s linear;
}
/*unloaded state*/
.gallery__image[data-src]{
opacity: 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With