user10031694
user10031694

Reputation: 221

How to display a component when page is loading in nuxt

I am quite new to nuxt, and I need help here.

async asyncData({ params, route }) {
    const { data } = await axios.get(
      `${process.env.baseUrl}/homes/?search=${
        params.search
      }&home_status=${1}`
    )
    return {
      homes: data.results,
    }
  }

I am trying to populate my component with data(using asyncData), but I want my skeleton loader to show if my page is loading. How do I do that in nuxt? Here is the code for my skeleton loader;

 <template>
    <div class="placeholder-container">
      <div class="placeholder wave">
        <div class="square"></div>
        <div class="line"></div>
        <div class="line"></div>
        <div class="line"></div>
      </div>
    </div>
</template>
<style scoped>
.placeholder-container {
  width: 35rem;
  margin: 15px auto 15px auto;
}

.placeholder {
  padding: 10px;
  width: 100%;
  // border: 1px solid lightgrey;
  display: flex;
  flex-direction: column;
}

.placeholder div {
  background: #e8e8e8;
}

.placeholder .square {
  width: 100%;
  height: 22rem;
  border-radius: 1rem;
  margin: 0 0 10px;
}

.placeholder .line {
  height: 12px;
  margin: 0 0 10px 0;
}
.placeholder .line:nth-child(2) {
  width: 120px;
}
.placeholder .line:nth-child(3) {
  width: 180px;
}
.placeholder .line:nth-child(4) {
  width: 150px;
}

.placeholder.wave div {
  animation: wave 1s infinite linear forwards;
  -webkit-animation: wave 1s infinite linear forwards;
  background: #f6f7f8;
  background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
  background-size: 800px 104px;
}

@keyframes wave {
  0% {
    background-position: -468px 0;
  }
  100% {
    background-position: 468px 0;
  }
}

@-webkit-keyframes wave {
  0% {
    background-position: -468px 0;
  }
  100% {
    background-position: 468px 0;
  }
}
</style>

What I normally do without using nuxt, is to create a data variable(loading=true), and change it to false after I finish making the api call, but since asyncData runs in the server, how do I make that work? I will also appreciate it if there is a better way of doing something like this

Upvotes: 4

Views: 7507

Answers (1)

tony19
tony19

Reputation: 138216

Placeholder

To display a placeholder component on a particular page during loading, switch from asyncData to the fetch hook, which exposes the $fetchState.pending flag that is set to true when complete:

<template>
  <div>
    <MyLoading v-if="$fetchState.pending" />
    <MyContent v-else :posts="posts" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      posts: []
    }
  },
  async fetch() {
    const { data } = await this.$axios.get(...)
    this.posts = data
  }
}
</script>

Customizing loading progress bar

Nuxt provides a default loading progress bar that appears at the top of the app while a page is loading. You could customize the progress bar's appearance:

// nuxt.config.js
export default {
  loading: {
    color: 'blue',
    height: '5px'
  }
}  

Or you could specify your own custom loading component instead:

// nuxt.config.js
export default {
  loading: '~/components/MyLoading.vue'
}

demo

Upvotes: 5

Related Questions