Vuetify 走马灯图片加载

8

我想使用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个回答

16
我发现 eager 属性是解决方案的一部分,但不是全部解决方案,因为它似乎只适用于嵌套内容。 将一个 v-img 标签嵌套在一个带有 eager 属性的 v-carousel-item 中,然后所有的图片都会预加载。
<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%"对我起了作用。


没错,仅有一个“eager”属性是不够的,感谢您的解决方案。 - Thinh NV
完美运行!谢谢 - CodeHacker

2
上面的代码看起来很好,它正常工作。
如果你想等到图像加载完成再显示,请在 "v-carousel-item" 组件中使用 "eager" 属性,
这个属性将强制组件内容在挂载时呈现。如果您有一些不会在 DOM 中呈现但希望被搜索引擎抓取的内容,这非常有用。
工作代码示例: 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',
        },
      ],
    }
  },
})

0

有一件事我想在问题上补充,就是关于“eager”。它会始终加载您走马灯中的每张图片,这让我很困扰,因为即使大多数情况下,您只想让它加载与当前图像相邻的图像,但它也会极大地增加流量。

为了实现这个目的(利用@ vue/composition-api),我通常使用这样一个类(它是用typescript编写的,但我想纯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",其中只包含紧挨着当前索引的项目。因此,每次在您的轮播中点击下一个或上一个按钮时,将加载更多的图像。此外,您可以使用占位符来填充数组(我在v-img的情况下使用数据URL和1px x 1px的图像,但如果您想使用分隔符,则只需要这样做,否则它们将不会显示正确的计数)。因此,使用此类,轮播将如下所示。
  <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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接