Каким образом можно добавить прелоадер во Vue 3, который будет отображаться до полной загрузки изображения?

Как можно оптимизировать загрузку изображений в компоненте post с использованием v-for, чтобы все изображения не стоит были загружены одновременно, а постепенно, чтобы улучшить пользовательский опыт?
  • 31 июля 2024 г. 4:43
Ответы на вопрос 2
Для добавления прелоадера в Vue 3 можно использовать директиву v-if, которая будет управлять отображением прелоадера до загрузки изображения. 

Пример использования прелоадера:

```vue
<template>
  <div>
    <img v-if="!imageLoaded" src="preloader.gif" alt="Loading...">
    <img v-else :src="imageSrc" alt="Image">
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageLoaded: false,
      imageSrc: 'image.jpg'
    }
  },
  mounted() {
    const image = new Image();
    image.onload = () => {
      this.imageLoaded = true;
    };
    image.src = this.imageSrc;
  }
}
</script>
```

Чтобы оптимизировать загрузку изображений в компоненте post с использованием v-for, можно использовать встроенный синтаксис директивы v-for для итерации по списку изображений и загружать их по одному. 

Пример оптимизированной загрузки изображений:

```vue
<template>
  <div>
    <div v-for="post in posts" :key="post.id">
      <img v-if="!post.loaded" :src="post.image" @load="post.loaded = true" alt="Post image">
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      posts: [
        { id: 1, image: 'image1.jpg', loaded: false },
        { id: 2, image: 'image2.jpg', loaded: false },
        { id: 3, image: 'image3.jpg', loaded: false }
      ]
    }
  }
}
</script>
```

Таким образом, используя итерацию по списку и загружая изображения по одному, можно улучшить пользовательский опыт и предотвратить загрузку всех изображений одновременно.
Можно сделать компонент-обертку для картинок и использовать его внутри post 
<!-- ImageWrapper.vue -->

<template>
  <div>
    <img v-if="isLoaded" :src="src" />
    <div v-else class="placeholder">Загрузка...</div>
  </div>
</template>


<script setup>
import { ref, onMounted } from 'vue';

const props = defineProps({
  src: {
    type: String,
    required: true
  }
});

const isLoaded = ref(false);

const loadImage = () => {
  const img = new Image();
  img.onload = () => {
    isLoaded.value = true;
  };
  img.src = props.src;
};

onMounted(() => {
  loadImage();
});
</script>

<Post
  v-for="post in posts"
  :key="post.id"
  :postData="post"
/>

<!-- Post.vue -->
<template>
  <div class="post">
    <ImageWrapper
      v-for="image in postData.images"
      :key="image.id
      :src=image.src"
    />
  </div>
</template>
Похожие вопросы