chinloyal
chinloyal

Reputation: 1141

Image loading issue with vue

This issue might not be specific to vue but here goes...

I'm searching for some items and retrieving them from a database, each item has a unique name which I use to load their image from an external site, for example:

<img :src="'https://external-site.com/photos/' + item.name + '.jpg'" />

Whenever I search for the first item it returns the item with it's image and details. But whenever I search for a second item, it returns the right details but uses the cached image of the last item until it's own image has loaded.

I decided I would use some events on the image to show a loader before they start loading but I only found that there were three events specific to images: onabort, onerror, onload.

But I need an event to show a loader at the start of downloading the image. If not, is there another way I can resolve this issue?

Upvotes: 4

Views: 8215

Answers (3)

Derzu
Derzu

Reputation: 7146

I had exactly the same issue. And none of the previous answers solved my problem.

At the method that change your items details and images link (ex.: changeDetails()), make a backup of your real image path (impath) at (impath_b) and set your image path to null. Vue.js will draw a transparent image, and after 100ms the real image path (impath) is restored.

changeDetails() {
    // for ...
    item.impath_b = item.impath; // it's not necessary declare impath_b before.
    item.impath = null;
    // ...

    // just before the method ends:
    setTimeout(function () {
        vm.revertImages();
    }, 100);
},
revertImages() {
    // for ...
    item.impath = item.impath_b;
    item.impath_b = null;
}

At the html code show the image just when it is not null:

<img v-if="item.file!=null" :src="item.file"/>
<img v-else :src="transpGif"/>

Define transpGif at your variables area:

transpGif: 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',

more details about this transpGif here .

The idea is to clean and redraw the images with an empty image, and then the new image will be drawn when it be loaded.

Upvotes: 0

chinloyal
chinloyal

Reputation: 1141

I solved the issue by using Progressive image rendering with vue:

First I installed a package that gave me a v-lazy-image component by npm i v-lazy-image then I imported the component

<script>
import VLazyImage from "v-lazy-image";

export default {
  components: {
    VLazyImage
  }
};
</script>

The component then allows you to specify the image and a placeholder image to use while the image loads:

<v-lazy-image
  :src="'https://external-site.com/photos/' + item.name + '.jpg'"
  src-placeholder="/images/default.jpg"
  />

You can see more details of this component here

Upvotes: 3

Jim B.
Jim B.

Reputation: 4704

A common trick to defeating the cache is to add an innocuous, changing parameter to your url, such as a timestamp:

<img :src="'https://external-site.com/photos/' + item.name + '.jpg?x=' + Date.now()" />

The parameter shouldn't interfere with accessing the image, but the browser won't assume the url is the same.

Upvotes: 2

Related Questions