Vue

by the94air

HTML

<div id="app">
  <h2>Users:</h2>
  <ol v-if="loading">
    <li>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
      <p class="skeleton"></p>
    </li>
  </ol>
  <ol v-else>
    <li v-for="user in users">
      <p>{{ user.name }}</p>
    </li>
  </ol>
</div>

CSS

body {
  padding: 20px;
  font-family: Helvetica;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

/* skeleton CSS */

.skeleton {
  height: 20px;
  width: 100%;
  background: #eee;
  margin: 8px 0;
  border-radius: .25rem;
  position: relative;
  overflow: hidden;
}

.skeleton::before {
  content: '';
  display: block;
  position: absolute;
  left: -150px;
  top: 0;
  height: 100%;
  width: 150px;
  background: linear-gradient(to right, transparent 0%, #E8E8E8 50%, transparent 100%);
  animation: load 1800ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite;
  background-repeat: no-repeat;
}

@keyframes load {
  from {
    left: -150px;
  }
  to   {
    left: 100%;
  }
}

Vue

new Vue({
  el: "#app",
  data: {
    loading: true,
    users: []
  },
  mounted() {
    return fetch('https://jsonplaceholder.typicode.com/users')
    .then(res => res.json())
    .then(data => {
    	this.users = data;
      this.loading = false;
    });
  }
})