JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@1.5.12/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@1.5.12/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons">

<div id="app">
  <v-app id="inspire">
    <v-layout>
      <v-flex xs12 sm6 offset-sm3>
        <v-container grid-list-sm fluid>
          <v-layout row wrap>
            <v-flex v-for="n in images" xs4 d-flex>
              <v-card flat tile class="d-flex">
                <v-img
                  :src="n.error ? noImageSrc : n.src"
                  @error="n.error = true"
                  aspect-ratio="1"
                  class="grey lighten-2"
                >
                  <template v-slot:placeholder>
                    <v-layout fill-height align-center justify-center ma-0>
                      <v-progress-circular
                        indeterminate
                        color="grey lighten-5"
                      ></v-progress-circular>
                    </v-layout>
                  </template>
                </v-img>
              </v-card>
            </v-flex>
          </v-layout>
        </v-container>
      </v-flex>
    </v-layout>
  </v-app>
</div>

JavaScript

new Vue({
  el: '#app',
  data: () => ({
    noImageSrc: 'https://via.placeholder.com/300x300',
    images: Array.from({ length: 9 }, (n, i) => ({
      error: false,
      // каждая третья картинка - мусор
      src: i % 3
        ? `https://placehold.co/300x300/${(Math.random() * 0x1000 | 0).toString(16).padStart(3, 0)}/FFF.png`
        : 'https://bullshit.com/bullshit.jpg',
    })),
  }),
});