기존의 CSR과 같은 데이터 호출 방식의 한계

// pages/main.vue

<template>
  <div>
    <p>This is Main Page</p>
    <div>
      {{products}}
    </div>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'MainView',
  data() {
    return {
      products: []
    }
  },
  async created() {
    const res = await axios.get('<http://localhost:3000/products>')
    this.products = res.data
  },
}
</script>

<style scoped>

</style>

실제로 해당 페이지에서 새로고침을 하면 깜빡이면서 잠시동안 [] 빈 배열이 보이다가 데이터가 채워진다. 하지만 SSR에서는 이미 필요한 페이지를 서버에서 미리 만들어놓고 받아오기만 해야 한다. 이렇게 페이지를 들고 와서 라이프사이클 훅을 사용하여 데이터를 fetching하고 기다렸다가 받은 데이터를 사용하는 SPA 방식은 SSR과 맞지 않다.

Data Fetching | Cracking Vue.js

asyncData

오로지 pages 하위에 존재하는 페이지 컴포넌트에서만 제공되는 속성이다. 해당 속성을 사용하면 데이터를 서버 사이드에서 받아와 미리 뿌려놓은 뒤 바로 클라이언트 측에서 보여줄 수 있다.

asyncData 안에서 **this를 사용하면 안 된다.** **컴포넌트가 생성되기 전에 서버사이드에서 미리 호출되기 때문에** 컴포넌트에 접근할 수 없기 때문이다.
<template lang="">
  <div>
    <ul>
    </ul>
  </div>
</template>
<script>
import axios from 'axios'

export default {
  data() {
    return {
      products: [],
    }
  },
  async asyncData() {
    const res = await axios.get('<http://localhost:3000/products>')
    console.log(res)
    **this.products = res.data  // 에러!!!!!!!!!!!!!!!!!!!!!!!!!**
  },
}
</script>
<style lang=""></style>

이 경우 밑과 같이 asyncData에서 데이터를 객체 형태로 리턴해주어 사용한다.

<template lang="">
  <div>
    {{ products }}
  </div>
</template>
<script>
import axios from 'axios'

export default {
  async asyncData() {
    const res = await axios.get('<http://localhost:3000/products>')
    const products = res.data
    **return { products }** // { products: products }
  },
}
</script>
<style scope></style>

이렇게 사용할 시, 해당 페이지에 접근했을 때 페이지가 깜빡거리면서 fetching을 기다릴 필요도 없이 이미 완성된 페이지가 바로 보여지는 것을 알 수 있다.