4

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

1 Answer 1

5

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

Sign up to request clarification or add additional context in comments.

3 Comments

I have tried using this, but its not what I am looking for. I want the loading bar to still display, but I want the skeleton loader to display on a particular page only when the data from my server is still being sent to the component. Just like youtube
Ok. I think Nuxt's fetch hook offers the solution here, as it provides a pending flag that could be used from the component. See updated answer.
What if I use asyncData but still need to handle loading status? Is it possible?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.