Data() VS asyncData() in Nuxt & vue
Asked Answered
H

3

13

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
Hypercorrect answered 1/12, 2018 at 8:41 Comment(0)
H
41

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.

Harbot answered 2/12, 2018 at 5:55 Comment(3)
so @merhawi-fissehaye what do I need to do to have simple button that calls some api from server? does that thing exist?Jdavie
Thanks a ton! Can you explain where is the code that is responsible to get data on the server? For example if I run Nuxt in frontend and some php framework in backend do I have to run some javascript in backend for SSR to work?Impala
@AhmadMobaraki your can have your backend code written in PHP and call an api from within asyncData. The SSR just works. You don't need to do anything extra.Harbot
H
5

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' }
  }
}
Horvitz answered 1/12, 2018 at 8:58 Comment(3)
so, when I have to use data() over asyncData()Hypercorrect
@xxyy asyncData for data that you need before page load. E.g. it will wait for http request to finish before actually render page unlike dataGabor
so lets say i have multiple pages where each page sends 30 items, when I add a button to go to page 2, should I call asyncdata manually or should I do a nuxt-linkWilltrude
C
1

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.

Cormack answered 13/10, 2021 at 8:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.