图像加载时的 Nuxt、Vuetify 骨架加载器

Nuxt, Vuetify skeleton loader while image loads

我找不到一个使用骨架加载器加载图像的合适示例。我正在使用 nuxt + Vuetify,我正在尝试使用带有框架加载器的简单图像。

这是我的代码。

<template>
  <v-skeleton-loader v-if="loading" :loading="loading" type="image">
    <v-card
      v-show="loaded"
      class="ma-auto elevation-4"
      shaped
      color="darkgreen"
      width="500"
      flat
    >
      <v-img
        src="/products/em-lucky-combo.jpg"
        max-width="500"
        @load="hasLoaded"
      >
      </v-img>
    </v-card>
  </v-skeleton-loader>
</template>

我的方法

<script>
export default {
  methods: {
    hasLoaded() {
      console.log('Image finished loading')

      this.loading = false
      this.loaded = true
    },
  },
}
</script>

但正如我所说,当方法在 v-card 标记内或直接在骨架加载器中时,它永远不会被调用。

我试过使用 @load,我试过使用如下安装的挂钩。

<script>
export default {
  mounted() {
    const readyHandler = () => {
      if (document.readyState === 'complete') {
        console.log('Document Rendered')
        this.loading = false
        this.loaded = true
        document.removeEventListener('readystatechange', readyHandler)
      }
    }

    document.addEventListener('readystatechange', readyHandler)

    readyHandler() // in case the component has been instantiated lately after loading
  },
}
</script>

但似乎没有什么能正常或优雅地工作。这是不可能的吗? <v-img> 标签位于骨架加载器内部或骨架加载器内的 v-card 内的那一刻,无论我做什么,它都不会被渲染。一个建议是使用插槽。我猜它与插槽有关,但我不明白如何使用它们。

我试过这样做。

<template v-slot:default>
  <v-card
    class="ma-auto elevation-4"
    shaped
    color="darkgreen"
    width="500"
    transition="fade-transition"
    flat
  >
    <v-img
      src="/products/em-lucky-combo.jpg"
      max-width="500"
      transition="fade-transition"
      @load="imageLoaded"
    ></v-img>
  </v-card>
</template>

我尝试使用下面的代码。

<v-img>
  <template #placeholder>
    <v-sheet>
      <v-skeleton-loader />
    </v-sheet>
  </template>
</v-img>

感谢@kissu,我意识到我的方法是错误和不必要的。我最终给我的图像设置了一些尺寸,并使用了一个带有占位符插槽的惰性图像加载器,效果很好。正如他提到的,我的图像是在本地加载的,所以在我的情况下它不会真正起作用。

我最后做了什么

<template>
  <v-card class="ma-auto elevation-4" flat shaped width="500">
    <v-img
      aspect-ratio="1"
      class="grey lighten-2"
      lazy-src=""
      max-height="350"
      max-width="500"
      src="/"
      transition="fade-transition"
    >
      <template v-slot:placeholder>
        <v-row
          align="center"
          class="fill-height ma-0"
          justify="center"
        >
          <v-progress-circular
            color="grey lighten-5"
            indeterminate
          ></v-progress-circular>
        </v-row>
      </template>
    </v-img>
  </v-card>
</template>

最后,OP 仅使用一些尺寸和延迟加载程序图像就足够了。由于图像是本地图像,因此不需要骨架。

<template>
  <v-card class="ma-auto elevation-4" flat shaped width="500">
    <v-img
      aspect-ratio="1"
      class="grey lighten-2"
      lazy-src=""
      max-height="350"
      max-width="500"
      src="/"
      transition="fade-transition"
    >
      <template v-slot:placeholder>
        <v-row
          align="center"
          class="fill-height ma-0"
          justify="center"
        >
          <v-progress-circular
            color="grey lighten-5"
            indeterminate
          ></v-progress-circular>
        </v-row>
      </template>
    </v-img>
  </v-card>
</template>