My approach bears a resemblance to Alphesh's solution, although I believe it offers improved readability. The concept involves establishing a straightforward queue system with three key properties:
- imagesToLoad - Represents the list of images/videos that need loading
- loadingImage - signifies the image currently being loaded
- loadedImages - indicates the images that have already been loaded
In addition to these properties, you will implement a simple method called queueNextImage
, which should be invoked by the mounted
hook (to initiate the loading of the initial image) and again once an image has finished loading. This method is structured as follows:
queueNextImage() {
if(this.loadingImage !== null) {
this.loadedImages.push(this.loadingImage)
}
this.loadingImage = this.imagesToLoad.shift()
}
At the outset, imagesToLoad
will contain all the URLs of the images you intend to load, while loadedImages
will be an empty array.
The template will iterate over the loadedImages
, displaying them in a standard loop, and include a single img
element where the src
attribute is bound to the value of loadingImage
. This element triggers the queueNextImage
function upon the onLoad
event of the image.
For a comprehensive example:
<template>
<div>
<p>
Images to load: <span>{{imagesToLoad.length}}</span>
Loading image: <span>{{loadingImage}}</span>
Images Loaded: <span>{{loadedImages.length}}</span>
</p>
<img v-for="item in loadedImages" v-bind:key="item" v-bind:src="item" />
<img v-on:load="queueNextImage" v-bind:src="loadingImage" />
</div>
</template>
<script>
export default {
mounted: function() {
this.queueNextImage();
},
methods: {
queueNextImage() {
if(this.loadingImage !== null) {
this.loadedImages.push(this.loadingImage);
}
this.loadingImage = this.imagesToLoad.shift();
},
},
data: () => ({
loadedImages: [],
loadingImage: null,
imagesToLoad: Array.from({length:200},(v,k)=>`https://via.placeholder.com/${k+850}`),
}),
};
</script>
Experiment with this on CodeSandbox.