【问题标题】:Load each item after the one before is finished loading in Vue JS在 Vue JS 中完成加载前一个项目之后加载每个项目
【发布时间】:2021-10-21 07:40:15
【问题描述】:

我需要为在线幻灯片演示加载大约 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>

【问题讨论】:

    标签: javascript performance vue.js vuetify.js preload


    【解决方案1】:

    解决方案:

    使用图像列表,您需要在每个图像上动态设置 src 属性,仅当加载前一个图像时

    步骤(5):

    1. 使用存储在 asrc 属性中的图像 URL 创建一个图像数据数组(您可以将其命名为任何名称)。
    2. 使用 v-for 指令从列表中渲染每个图像。
    3. 将图像 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>

    【讨论】:

      【解决方案2】:

      这类似于 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的值,并从queueNextImage触发onLoad图片事件。

      完整示例:

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

      Try it on CodeSandbox.

      【讨论】:

        【解决方案3】:

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

        将您的代码包装在此组件中,您的 html 将根据可见性加载。

        【讨论】:

        【解决方案4】:

        您需要使用图像预加载。 如果您使用 Nuxt.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 中有一些图像预加载的示例 Vuetify carousel image loading

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

        【讨论】:

          【解决方案5】:

          据我了解,您希望按索引的升序一张一张地加载图像。

          您可以尝试以下一种方法:

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

          伪代码示例

          1. 先替换vue模板中的代码
          <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;
                  });
              }
          

          【讨论】:

          • 感谢您的回答。您能否进一步解释一下或提供一个例子?我应该在哪里调用 loadImages() 函数?
          • @Tom 你可以在页面加载完毕或者组件挂载后调用 loadImages 方法,它会自动更新图片。
          猜你喜欢
          • 2022-07-23
          • 1970-01-01
          • 2020-10-18
          • 1970-01-01
          • 2023-01-03
          • 2020-11-21
          • 2022-01-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多