Data() VS asyncData() in Nuxt & vue

2020-06-20 05:42发布

问题:

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

回答1:

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.



回答2:

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' }
  }
}