[Vue.js] SPA 튜토리얼 — Part1
프로젝트 세팅, Axios를 활용한 API 데이터 호출 - Price
Step 1: 프로젝트 세팅
[Ready] 실행 환경의 OS에 맞는 Node.js, Vue CLI 가 설치 되어 있어야 합니다.
Vue CLI 최신 버전 기준으로 프로젝트를 생성합니다. (Vue CLI 설치)
아래 설정을 참고하여 메뉴얼 모드로 Preset 설정을 진행합니다.
vue create live-cryptocurrencyVue CLI v3.3.0
┌───────────────────────────┐
│ Update available: 3.7.0 │
└───────────────────────────┘? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, CSS Pre-processors, Linter
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No✨ Creating project in D:\front-end\vue\live-cryptocurrency.
🗃 Initializing git repository...
⚙ Installing CLI plugins. This might take a while...📄 Generating README.md...🎉 Successfully created project live-cryptocurrency.
👉 Get started with the following commands:$ cd live-cryptocurrency
$ npm run serve
npm run serve 명령이 정상적으로 실행되면 콘솔에서 아래와 같은 메시지를 확인할 수 있습니다.
DONE Compiled successfully in 12898ms 17:37:17App running at:
— Local: http://localhost:8080/
— Network: http://192.168.0.xxx:8080/Note that the development build is not optimized.
To create a production build, run npm run build.
http://localhost:8080/ 경로에 접속하면 프로젝트 기본 설정으로 구성되는 아래와 같은 웰컴 화면을 확인할 수 있습니다.
Step 2: API 요청
비트코인(BTC), 이더리움(ETH), 리플(XRP)의 한화(KRW) 가격 및 등락률 데이터를 요청해서 화면에 표 형식으로 출력할 계획입니다.
암호 화폐 실시간 가격 데이터를 제공하는 Open API 중 목적에 부합하는 서비스를 찾아서 테스트 요청을 시도해봅니다.
Open API : Cryptocompare.com (Price, Ratio, News)
Request URL : https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,ETH,XRP&tsyms=KRW
아래 화면의 상단 입력 영역에 Request URL을 입력하고 Execute Call 버튼을 선택합니다.
Response 영역에 기대했던 결과값을 확인하고, 실제 코드 수준에서의 사용을 위해 Get a free key 버튼을 선택합니다.
가입과 로그인 프로세스 완료 후 Get a free key 버튼을 다시 선택하여 API Key를 발급받고 아래 요청을 수행합니다.
https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,ETH,XRP&tsyms=KRW&api_key=발급받은API Key
GET 요청이기 때문에 브라우저에서 바로 확인 할 수 있습니다.
[Response 데이터 샘플 ]
{
"RAW": {
"BTC": {
"KRW": {
"PRICE": 6130238.03,
"CHANGEPCT24HOUR": 0.06215658987244043
}
},
"ETH": {
"KRW": {
"PRICE": 182889.95,
"CHANGEPCT24HOUR": -0.4627782718931592
}
},
"XRP": {
"KRW": {
"PRICE": 346.22,
"CHANGEPCT24HOUR": -0.1586065691957074
}
}
},
"DISPLAY": {
"BTC": {
"KRW": {
"PRICE": "₩ 6,130,238.0",
"CHANGEPCT24HOUR": "0.06"
}
},
"ETH": {
"KRW": {
"PRICE": "₩ 182,890.0",
"CHANGEPCT24HOUR": "-0.46"
}
},
"XRP": {
"KRW": {
"PRICE": "₩ 346.22",
"CHANGEPCT24HOUR": "-0.16"
}
}
}
}
Response 데이터 구조는 JSON 형식이고, Raw와 Display 두 가지 형식으로 데이터 쌍이 구성되어 있습니다.
일반적으로 Raw 데이터를 Front-end에서 가공하여 Display에서 제공하는 형식으로 포멧을 맞추게 되는데, 두 가지 형식으로 데이터를 제공하는 것으로 보아 후처리의 수고스러움을 줄여주기 위한 의도로 보여집니다.
API Key 발급과 데이터 호출 테스트를 완료했으니 이제 코드 수준의 적용을 진행해볼 차례입니다.
Step 3: 코드 구현
API 요청을 처리하기 위해 Vue.js, React 구분 없이 널리 사용되는 Axios 라이브러리를 설치합니다.
npm install axios --save
/App.vue
<template>
<div id="app">
<router-view/>
</div>
</template><style lang="scss">
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
프로젝트 세팅에서 라우터 설정을 했기 때문에 router.js에 정의한 path와 component를 매칭해서 <router-view/> 영역에 내용을 보여주게 됩니다.
/router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'Vue.use(Router)export default new Router({
routes: [{
path: '/',
name: 'home',
component: Home,
meta: {
title: 'Live Cryptocurrency'
}
}]
})
/src/views/Home.vue
<template>
<div class="home">
<Cryptocurrency/>
</div>
</template>
<script>
import Cryptocurrency from '@/components/Cryptocurrency.vue'
export default {
name: 'home',
components: {
Cryptocurrency
}
}
</script>
Views 폴더에 있는 Home.vue 에서는 Cryptocurrency.vue 컴포넌트를 호출하고 있습니다.
/src/components/Cryptocurrency.vue
<template>
<div>
<header>
<h1>Live Cryptocurrency</h1>
</header>
<article>
<h2>Live Prices</h2>
<table>
<caption>Live Cryptocurrency</caption>
<thead>
<tr>
<th>BTC/KRW</th>
<th>ETH/KRW</th>
<th>XRP/KRW</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{cryptoPrice.BTC}}</td>
<td>{{cryptoPrice.ETH}}</td>
<td>{{cryptoPrice.XRP}}</td>
</tr>
</tbody>
</table>
</article>
</div>
</template><script>
// Add modules
import axios from 'axios'// Singl file component scope
export default {
name: 'cryptocurrency',
// 데이터 객체
data() {
return {
cryptoPrice: {
BTC: 0,
ETH: 0,
XRP: 0
}
}
},
// Vue 인스턴스에 추가할 메소드
methods: {
// 암호 화폐 가격 정보 처리
bindData() {
axios
.get('https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,ETH,XRP&tsyms=KRW&api_key=발급받은API Key')
.then(res =>{
console.log('API Response : ', res); const obj = Object.keys(this.cryptoPrice) for(var i=0;i<obj.length;i++){
this.cryptoPrice[obj[i]] =
res.data.DISPLAY[obj[i]].KRW.PRICE
console.log(obj[i] + ' : ' + this.cryptoPrice[obj[i]]);
}})
.catch(e => {
console.log(e);
})
}
},
// 컴포넌트, 템플릿, 렌더링된 돔에 접근할 수 있는 상태 (인스턴스 라이프사이클에 속함)
mounted() {
this.bindData()
},
}
</script><style lang="scss">
body{
min-width:360px;
margin:0
}article{
padding:10px
}.blind {
visibility: hidden;
position: absolute;
left: 0;
top: 0;
width: 1px;
height: 1px;
line-height: 0;
font-size: 0;
}header {
height: 64px;
border-bottom: 2px solid #2a3b52;
background: #2e4564;
}h1 {
margin: 0;
padding: 24px 0 0;
color: #fff;
font-size: 18px;
text-transform: uppercase;
}h2 {
margin: 0;
padding: 6px 0 15px;
color: #333;
font-size: 16px;
font-weight: bold;
text-align: left;
text-transform: uppercase;
}table {
width: 100%;
margin-bottom: 20px;
table-layout: fixed;
border-collapse: collapse;
border-top: 1px solid #ccc;
text-align: center;
font-size: 12px;
line-height: 1.5;
caption {
position: absolute;
left: 0;
top: 0;
width: 1px;
height: 1px;
font-size: 0;
line-height: 0;
}
thead th {
padding: 10px;
font-weight: 700;
vertical-align: top;
color: #369;
border-bottom: 3px solid #036;
}
tbody th {
width: 150px;
padding: 10px;
font-weight: 700;
vertical-align: top;
border-bottom: 1px solid #ccc;
background: #f3f6f7;
}
td {
width: 350px;
padding: 10px;
vertical-align: top;
border-bottom: 1px solid #ccc;
}
}</style>
Cryptocurrency.vue 주요 구문
// ① HTML 템플릿 구문
<tr>
<td>{{cryptoPrice.BTC}}</td>
<td>{{cryptoPrice.ETH}}</td>
<td>{{cryptoPrice.XRP}}</td>
</tr>
// ② 데이터 객체
data() {
return {
cryptoPrice: {
BTC: 0,
ETH: 0,
XRP: 0
}
}
},
// ③ Vue 인스턴스에 추가할 메소드
methods: {
// 암호 화폐 가격 정보 처리
bindData() {
axios
.get(API Request URL)
.then(res => {
const obj = Object.keys(this.cryptoPrice)
for (var i = 0; i < obj.length; i++) {
this.cryptoPrice[obj[i]] =
res.data.DISPLAY[obj[i]].KRW.PRICE
}
.catch(e => {
console.log(e);
})
})
}
},
//컴포넌트, 템플릿, 렌더링된 돔에 접근할 수 있는 상태 (인스턴스 라이프사이클에 속함)
mounted() {
this.bindData()
},
② 데이터 객체를 ① HTML 템플릿에서 이중 중괄호 {{ }} 구문으로 바인딩 시킬 수 있습니다.
③ 이벤트와 메소드 를 통해서 데이터 객체를 변경하면 바인딩된 콘텐츠도 업데이트 됩니다.
[데이터 흐름]
- 데이터 객체 내의 cryptoPrice.BTC, cryptoPrice.ETH, cryptoPrice.XRP는 0 으로 초기화
- 초기화된 값은 호출된 {{ }} 영역으로 매칭
- Vue 라이프사이클에 따라 mounted 상태에 bindPrice() 함수 실행
- bindData() 함수에서는 Axios 로 API에 GET 요청을 보내고 결과값이 있으면 then 구문을 수행, 오류가 발생되면 catch 구문에서 오류 출력
then 구문에서는 Ajax 요청 결과값을 res 인자로 매칭하여 DISPLAY > [BTC, ETH, XRP] > KRW > PRICE 노드에 접근하여 출력에 적합한 형식의 결과값을 데이터 객체에 업데이트 - 데이터 객체 업데이트로 인해 HTML 템플릿에 매칭된 콘텐츠도 업데이트
Part 2 에서는 24시간 변동률, 최근 뉴스 구성에 대해 다뤄보도록 하겠습니다.
완성된 결과물은 http://fe.hivelab.co.kr/spa 페이지에서 확인할 수 있습니다.
[▣] [Vue.js] SPA 튜토리얼 — Part1
프로젝트 세팅, Axios를 활용한 API 데이터 호출 — Price