在Vue JS中加载完前一项后再加载每一项



我需要为在线幻灯片演示加载大约1000个静态图像,gif和视频。目前所有的项目都是一次加载,观众需要等待看到第一个项目。在前一项装载完成后,如何装载每一项?

Vue.js Vuetify.js代码:

<v-row v-for="(objkts, index) in group" :key="index">
<v-col v-for="objkt in objkts" :key="objkt.id">
<v-card :key="index" width="100vh">
<v-img
max-width="100vh"
:src="img(objkt)"
></v-img>
</v-card>
</v-col>
</v-row>

解决方案:

使用图像列表,你需要动态设置src属性

步骤(5):

  1. 创建一个图像数据数组,图像URL存储在asrc属性中(你可以给它取任何名字)。
  2. 使用v-for指令渲染列表中的每个图像。
  3. 设置image src为image。用src代替asrc
<img 
v-for="(image,index) in group" :key="index"
:src="image.src"
  1. 还设置了一个图像加载事件来调用下一个图像的加载
<img 
v-for="(image,index) in group" :key="index"
:src="image.src"
@load="loadNextimage(index)"/>
  1. 每当图像加载器被调用时,添加src属性到图像。这将开始加载图像。
loadNextimage(currentIndex){
let nextIndex = currentIndex+1
if( nextIndex < this.group.length){
let img = this.group[nextIndex]
img.src = img.asrc
delete img.asrc
Vue.set(this.group, nextIndex, img)
}
}

new Vue({
el: '#app',
data(){

return {
group: [
{ id: 1, title: '', asrc: 'https://source.unsplash.com/collection/190727/120x120'},
{ id: 2, title: '', asrc: 'https://source.unsplash.com/collection/8961198/120x120'},
{ id: 3, title: '', asrc: 'https://source.unsplash.com/collection/190723/120x120'},
{ id: 4, title: '', asrc: 'https://source.unsplash.com/collection/KizanWcExgU/120x120'}
]
}
},
mounted(){
this.loadNextimage(-1)
},
methods:{
loadNextimage(currentIndex){
let nextIndex = currentIndex+1
if(nextIndex<this.group.length){
let img = this.group[nextIndex]
img.src = img.asrc
delete img.asrc
Vue.set(this.group,nextIndex,img)
}
}
}
});
img {
height: 120px;
width:120px;
}
img:not([src]){
background: url(https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg);
background-size:cover;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<div id="app">
<img 
v-for="(image,index) in group" :key="index"
:src="image.src"
@load="loadNextimage(index)"
>
</div>

这与Alphesh的解决方案类似,但我认为它更容易阅读。这个想法是建立一个简单的排队系统,它有三个属性:

  1. imagesToLoad-需要加载的图片/视频列表
  2. loadingImage-当前正在加载的图像
  3. loadedImages-已经加载的图片

你还有一个简单的方法叫做queueNextImage,它应该被mounted钩子调用(开始第一个图像加载),然后当图像加载完成时再次调用,看起来像这样:

queueNextImage() {
if(this.loadingImage !== null) {
this.loadedImages.push(this.loadingImage)
}
this.loadingImage = this.imagesToLoad.shift()
}

当你启动imagesToLoad将填充所有的图像url,你想加载和loadedImages将是一个空数组。

模板将迭代loadedImages,在常规循环中呈现它们,并且将有一个img元素,其src属性绑定到loadingImage的值,并从图像的onLoad事件中触发queueNextImage

完整的示例:

<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>

在CodeSandbox上试试。

您可以从vuetify: https://vuetifyjs.com/en/components/lazy/使用lazy组件

将你的代码封装在这个组件中,你的html将根据可见性加载。

您需要使用图像预加载。如果你使用next .js,你可以在构建时加载数据并显示所有资产。图像预加载:https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image

你可以在延迟模式下渲染图像https://css-tricks.com/lazy-loading-images-with-vue-js-directives-and-intersection-observer/

在Vuetify中有一些图像预加载的例子验证carousel图像加载

或者您可以使用此组件进行预加载https://github.com/vuetifyjs/vuetify-loader

据我所知,您希望按照索引升序依次加载图像。

你可以尝试这样一种方法:

  • 创建async方法和await在循环中加载图像。

伪代码示例:

  1. 首先替换vue模板
  2. 中的代码
<v-img
max-width="100vh"
:src="imgCollection[index]"
></v-img>
  1. 然后依次异步加载图片
async function loadImages() {
imagesList.forEach((img, index) => {
var data = await getImageData(img.url);

// update the data into your array
imgCollection[index] = data;
});
}

最新更新