nuxt.js 시작하기 - 003
Nuxt.js 의 데이터 호출 방식과 API 연동
백엔드 API 서버 구성
https://github.com/joshua1988/learn-nuxt/tree/master/backend 접속
$ git clone https://github.com/joshua1988/learn-nuxt.git
$ cd learn-nuxt
backend 폴더를 진행중인 프로젝트 폴더에 복사
json 서버 실행
# 진행중인 프로젝트 폴더에서
$ cd backend
$ npm i
$ npm run dev
localhost:3000 에서 backend 가 실행됨
프로젝트에서 nuxtjs 를 실행하고 있다면 종료 후 npm run dev
해야 함
localhost:3000 에서 json 서버 접속 확인
JSON Server 소개
https://jsonplaceholder.typicode.com/
https://github.com/typicode/json-server
json Server는 mock API 를 제공
nuxtjs 의 데이터 요청 속성 (data fetching) 을 통해 아래 데이터 조회가능
- localhost:3000/products
- localhost:3000/carts
구글에서 json server github 검색 > github repo 확인하면 파일기반의 REST API 서버 생성에 대해 참고할 수 있음
axios 설치 및 API 호출
nuxtjs 를 중지한 후 json 서버가 3000 에 실행시키고 nuxtjs 를 재실행할 것
# backend 폴더로 이동
$ cd backend
$ npm run dev
# port 3000 에 json server 가 실행됨
# 프로젝트 폴더로 이동
$ cd ..
$ npm run dev
# 임의의 port 에 nuxtjs 가 실행됨 ex) 51542
axios 설치
# 프로젝트 폴더에서
$ npm i axios
pages/main.vue 에 axios 를 통해 호출
...
<scirpt>
import axios from 'axios';
export default {
async created() {
const response = await axios.get('http://localhost:3000/products');
console.log(response);
}
}
</script>
개발자도구 console 창에 products 목록확인이 출력
서버 포트 변경 및 받아온 데이터 표시
nuxtjs 호스트와 포트 변경
https://nuxtjs.org/docs/features/configuration/#edit-host-and-port
nuxt.config.js 파일에 포트를 지정
{
...
},
// server setup
server : {
port:5000,
}
}
nuxtjs 재실행
$ npm run dev
nuxtjs 가 포트 5000 으로 실행되는 것을 확인
code - preference - keyboard shortcuts 로 설정
pages/main.vue 에 있는 console.log 로 보이는 products 를 화면에 표시
<template>
<div>
...
<div>
</div>
</div>
</template>
...
<script>
...
export default {
data() {
return {
products: [],
}
},
async created() {
const response = await axios.get('http://localhost:3000/products')
console.log(response)
this.products = response.data
}
...
}
</script>
HMR(Hot Module Replacement) 에 의해 화면이 변경되면서 표시됨
CSR 으로는 데이터가 표시되는 시간이 무조건 필요함
이는 네트워크 반응속도에 따라 콘텐츠가 느리게 표현될 수 있음. 최소 깜빡이는 현상이 나타남
이를 SSR 인 nuxtjs 을 통해 해결할 수 있음
https://joshua1988.github.io/webpack-guide/devtools/hot-module-replacement.html
Nuxt 데이터 호출 방식 안내
https://joshua1988.github.io/vue-camp/nuxt/data-fetching.html
CSR 에서는 라이프 사이클 훅을 사용하여 컴포넌트가 생성되자마자 서버에 데이터를 요청해 받아온 값을 화면에 표시하였음
SSR 에서는 서버에서 데이터를 모두 포함한 페이지를 클라이언트로 전달해야 함
nuxsjs 에서는 asyncData, fetch 라는 2가지 인스턴스 옵션 속성을 이용하여 처리할 수 있음
asyncData 속성
asyncData 속성은 페이지컴포넌트(pages 폴더 아래에 있는 컴포넌트)에만 제공되는 속성임
...
<script>
import axios from 'axios';
export default {
// params의 id가 1이라고 가정
async asyncData({ params, $http }) {
const response = await axios.get(`/users/${params.id}`);
const user = response.data;
return { user }
}
}
</script>
...
asyncData 적용 및 ESLint 규칙 확인
asyncData 를 추가
eslint-plugin-vue 에 의해 asyncData 를 추가하면 export default 의 상단으로 이동됨
상단으로 이동되지 않으면 아래 강의노트 참고하여 .eslintrc.js 파일 수정
https://eslint.vuejs.org/rules/order-in-components.html
ESLint와 Prettier 설정 하기
https://joshua1988.github.io/vue-camp/format/official.html
pages/main.vue 에 asyncData() 적용
...
<script>
...
export default {
async asyncData() {
const response = await axios.get('http://localhost:3000/products');
console.log(response);
this.products = response.data;
}
}
...
this.products 의 this 에서 오류가 발생
왜 this 가 사용이 불가능할까?
asyncData 속성 안내 및 코드 수정
https://joshua1988.github.io/vue-camp/es6/enhanced-object-literals.html#축약-문법-1-속성과-값이-같으면-1개만-기입
asyncData 의 예제코드를 보면 this 에서 오류가 발생하는 이유를 알 수 있음
...
<script>
export default {
async asyncData({ params, $http }) {
const response = await axios.get(`/users/${params.id}`);
const user = response.data;
return { user }
}
}
</script>
...
asyncData 는 비동기데이터를 호출하는 인스턴스 속성임
asyncData 는 기본적으로 페이지를 진입하기 전에 호출하여 뷰 인스턴스 데이터 객체로 리턴함
따라서 asyncData 는 컴포넌트가 생성되기 전에 실행되므로 컴포넌트 생성 이 후 사용가능한 this 는 사용이 불가함
따라서 asnycData 에 문제가 있으면 페이지가 표시되지 않음
asyncData 속성 주의사항
pages 폴더에 있는 컴포넌트가 아니면 asyncData() 입력 시 오류 발생
<template>
<div>
<p>메인 페이지입니다</p>
<ProductList><ProductList/>
</div>
</template>
<script>
import axios from 'axios';
import ProductList from '~/components/ProductList.vue';
// ...
</script>
components/ProductList.vue 생성
<template>
<div>
</div>
</template>
<script>
// ...
export default {
async asyncData() {
const response = await axios.get('http://localhost:3000/products');
console.log(response);
return { product }
}
}
</script>
<style>
</style>
오류가 발생함. 이유는 ProductList.vue 가 페이지 컴포넌트가 아니기 때문임
asyncData 속성 정리
asyncData 의 params, $http 는 무엇일까?
asyncData 는 페이지에 진입하기 전에 호출되고, return 으로 뷰 인스턴스 데이터 객체를 반환