Reputation: 1141
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
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
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
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