Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data() VS asyncData() in Nuxt & vue

Both data() and async data() gives the same result (and it is obvious that the results from asyncData() override the results from data())

and both results in HTML code in the source code (i.e the code rendered in the server-side)

also, both can be used to "await" the data to be fetched (ex: using axios)

so, what is the difference between them?

<template>
    <div>
        <div>test: {{ test }}</div>
        <div>test2: {{ test2 }}</div>
        <div>test2: {{ test3 }}</div>
        <div>test2: {{ test4 }}</div>
    </div>
</template>

<script>
export default {
    asyncData(app) {
        return {
            test: "asyncData",
            test2: "asyncData2",
            test3: "asyncData3"
        };
    },
    data() {
        return {
            test: "data",
            test2: "data2",
            test4: "data4"
        };
    },
};
</script>

result:

test:  asyncData
test2: asyncData2
test2: asyncData3
test2: data4
like image 313
xx yy Avatar asked Dec 01 '18 08:12

xx yy


3 Answers

The simplest answer is data() is processed on the client side, however asyncData() section is processed on the server side on the call for Nuxt() once and on the client side once more.

The biggest advantage of nuxt is it's ability to render content on the server side. If you load your content using promise on the client side, say for example in the mounted section as:

data() {
  return {
    products: []
  }
},

mounted() {
  axios.get('/api/v1/products').then(response => {
    this.products = response.data
  })
}

the javascript code is sent to the client as it is and the browser is responsible to run the promise to fetch the data from the api. However if you put the promise inside asyncData:

asyncData() {
  return axios.get('/api/v1/products').then(response => {
    // Note that you can't access the `this` instance inside asyncData
    // this.products = response.data
    let products = response.data
    return { products } // equivalent to { products: products }
  })
}

The data fetching is done on the server side and the result is pre-rendered and an html with the data (rendered into it) is sent to the client. So in this case the client won't be receiving the javascript code to process the api call by itself, but instead it receives something like this:

<ul>
  <li>
    <a href="#">Product 1</a>
  </li>
  <li>
    <a href="#">Product 2</a>
  </li>
  <li>
    <a href="#">Product 3</a>
  </li>
</ul>

The result we return from asyncData is merged with what is in data. It's not replaced but merged.

like image 52
Merhawi Fissehaye Avatar answered Oct 22 '22 16:10

Merhawi Fissehaye


You may want to fetch data and render it on the server-side. Nuxt.js adds an asyncData method that lets you handle async operations before setting the component data.

asyncData is called every time before loading the page component and is only available for such. It will be called server-side once (on the first request to the Nuxt app) and client-side when navigating to further routes. This method receives the context object as the first argument, you can use it to fetch some data and return the component data.

The result from asyncData will be merged with data.

export default {
  data () {
    return { project: 'default' }
  },
  asyncData (context) {
    return { project: 'nuxt' }
  }
}
like image 44
Ismoil Shifoev Avatar answered Oct 22 '22 15:10

Ismoil Shifoev


Nuxt's main attraction is the serverside rendering part, that helps with SEO. So we can assume any deviation from the normal "Vue-way" of doing things is most likely because it is in service of the SSR (which Vue naturally doesn't allow, hence we use Nuxt). Knowing that, we can pretty much say asyncData() contains the SEO-focused data that is send on the first page-load.

Short answer => use asyncData() for fetched template-based SEO-focused content.

like image 34
Dave Snijder Avatar answered Oct 22 '22 15:10

Dave Snijder