Vuetify轮播图片加载

时间:2020-03-11 02:34:04

标签: vue.js vuetify.js

我想使用vuetify的轮播显示一些图像。但是在第一次滑动时,过渡时会出现白色闪烁,就像图像在尝试渲染之前没有加载一样。

<div id="app">
  <v-app id="inspire">
    <v-carousel>
      <v-carousel-item
        v-for="(item,i) in items"
        :key="i"
        :src="item.src"
      ></v-carousel-item>
    </v-carousel>
  </v-app>
</div>

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      items: [
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',
        },
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',
        },
      ],
    }
  },
})

演示,您可以在其中查看我在说什么:https://codepen.io/gaalee89/pen/RwPQWXj

有没有办法解决这个问题?谢谢。

3 个答案:

答案 0 :(得分:2)

我发现eager属性 是解决方案的一部分,而不是整个解决方案,因为它似乎仅适用于嵌套内容。 在v-carousel-item内嵌套一个v-img标签,并在其上都具有eager属性,然后所有图像都会预加载。

<div id="app">
  <v-app id="inspire">
    <v-carousel>
      <v-carousel-item
        v-for="(item,i) in items"
        :key="i"
        eager
      >
        <v-img :src="item.src" height="100%" eager/>
      </v-carousel-item>
    </v-carousel>
  </v-app>
</div>

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      items: [
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',
        },
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',
        },
      ],
    }
  },
})

然后,您需要调整布局,因为图像内容的行为会有所不同。 v-img上的height =“ 100%”对我有用。

答案 1 :(得分:1)

上面的代码看起来不错,可以正常工作。

如果要等到图像加载完毕,请在“ v-carousel-item” 组件

中使用“渴望” 属性

此属性将强制组件内容在安装时渲染。 如果您的内容不会在 您要抓取SEO的DOM

有效的Codepen:https://codepen.io/chansv/pen/dyodXPP

<div id="app">
  <v-app id="inspire">
    <v-carousel>
      <v-carousel-item
        eager
        v-for="(item,i) in items"
        :key="i"
        :src="item.src"
      ></v-carousel-item>
    </v-carousel>
  </v-app>
</div>

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      items: [
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',
        },
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',
        },
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',
        },
        {
          src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',
        },
      ],
    }
  },
})

答案 2 :(得分:0)

我要添加到问题和关于渴望的一件事。 Eager 总是会加载您的轮播中的每张图片,这总是困扰着我,因为即使大部分时间您只想加载与当前图片相邻的图片,它也会极大地增加流量。

为此(使用@vue/composition-api)我通常使用这样的类(它是用打字稿编写的,但我想它对于纯 JavaScript 用户也应该是可读的)


import { reactive, toRef, watch } from '@vue/composition-api';

export class ArrayAdjacentController<T> {
  allItems: T[];
  availableItems: T[];
  currentIndex: number;

  constructor(items: T[], placeholder?: T){
    this.allItems = items;
    this.availableItems = this.allItems.slice(0,2);
    this.currentIndex = 0;

    if(placeholder){
      for(let i=2; i<this.allItems.length; i++)
        this.availableItems.push(placeholder);
    }

    reactive(this);

    const currentIndexRef = toRef(this, 'currentIndex');

    watch(currentIndexRef, val => {
      this.setItem(val);
      this.setItem(val-1);
      this.setItem(val+1);
    });
  }

  setItem(index:number){
    if(this.allItems[index] !== this.availableItems[index])
      this.availableItems[index] = this.allItems[index];
  }

  setCurrent(number:number){
    if(number>= this.allItems.length || number < 0)
      throw new Error(`ImageDataController: ${number} out of index`);
    this.currentIndex = number;
  }
}

这基本上是创建一个数组“availableItems”,而不是只包含 currentIndex 旁边的项目。因此,每次您在轮播中点击 next 或 prev 时,都会再加载一张图片。您也可以使用占位符来填充数组(在 v-img 的情况下,我使用带有 1px x 1px 图像的数据 url 但如果您想使用分隔符,则只需要它,否则它们不会显示在正确计数)。所以有了这个类,旋转木马看起来像这样

  <v-carousel v-model="internalImages.currentIndex">
    <v-carousel-item
      v-for="(img, ind) of internalImages.availableItems" 
      :key="ind"
      eager
    >
      <v-img
        :src="img"
        eager
      />
    </v-carousel-item>
  </v-carousel>