[Vue.js] SPA 튜토리얼 — Part3

News 데이터 컨트롤 - More 버튼

주재승
hivelab-dev
6 min readMay 7, 2019

--

Step 1: News - More

Part2 에서 구현한 내용에 이어서 더보기 버튼(More) 클릭에 대응하는 기능을 추가해보도록 하겠습니다.

Cryptocurrency.vue 주요 구문

// HTML 템플릿 구문
<article>
<div class="h_area">
<h2>Recent News</h2>
</div>
<ul>
<li v-for="item in news" :key="item.id">
<a :href="item.url">
<div class="bx_thumb">
<img :src="item.imageurl" width="60" height="60" :alt="item.body">
</div>
<dl>
<dt>[{{item.published_on | moment}}] {{item.title}} </dt>
<dd>
<p>{{item.body}}</p>
</dd>
</dl>
</a>
</li>
</ul>
<button
type="button"
v-on:click="appendNews()"
:disabled="this.dataFull === true"
:class="{disabled : dataFull}"
>
More ({{cntNews}}/{{totNews}})
</button>
</article>
// 데이터 객체
data() {
return {
newsAll: {}, // 전체 뉴스 데이터
news: {}, // 화면에 노출되는 뉴스 데이터
totNews: 0, // 전체 뉴스 데이터 수
cntNews: 5, // 화면에 노출할 뉴스 데이터 수 (초기 세팅 = 5)
dataFull: false, // 전체 데이터보다 많은 데이터 호출 여부
}
},

// Vue 인스턴스에 추가할 메소드
methods: {
// 암호 화폐 뉴스 정보 처리
bindNews() {
axios.
get('https://min-api.cryptocompare.com/data/v2/news/?lang=EN')
.then(res => {
let data = []
for(var i=0;i<this.cntNews;i++){
data.push(res.data.Data[i])
}

this.newsAll = res.data.Data
this.news = data
this.totNews = this.newsAll.length
})
.catch(e => {
console.log(e);
})
},
appendNews(){
// 전체 뉴스 개수보다 노출되는 뉴스 개수가 작은 경우
if(this.cntNews < this.totNews){
this.cntNews += 5 // 노출 뉴스 개수 5개 증가
let data = []
for(var i=0;i<this.cntNews;i++){
data.push(this.newsAll[i]) // 전체 뉴스에서 노출 뉴스 개수만큼 데이터 추출하여 data 배열에 추가
}
this.news = data // news 객체에 data 배열 업데이트
// 전체 뉴스 개수와 노출되는 뉴스 개수가 같으면
}else{
this.dataFull = true // dataFull 객체를 true 상태로 변경
alert('List items are fully loaded!') // 모든 데이터 출력 알림
}
}
},
//컴포넌트, 템플릿, 렌더링된 돔에 접근할 수 있는 상태 (인스턴스 라이프사이클에 속함)
mounted() {
this.bindNews()
},
<style lang="scss">
button {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
margin: 0;
padding: 20px 0 19px;
border: 0;
border-top: 2px solid #1b212f;
background: #1d2943;
color: #fff;
font-size: 14px;
cursor: pointer;
}
.disabled{
border-top: 2px solid #e1e1e1;
background:#e9e9e9;
color:#777
}
</style>

[데이터 흐름]

  1. bindNews() - 초기 렌더링에서 수행
    - API 데이터 요청
    - 기사 목록 출력 5개
    - 버튼에 (출력/전체) 기사 데이터 수 업데이트
  2. appendNews() - More 버튼 클릭시에 수행
    - 기사 목록 출력 +5개
    - 버튼에 출력 기사 데이터 수 업데이트 +5
    - 전체 데이터가 출력된 상황(50/50) 에서 다시 버튼을 선택하는 경우
    1) dataFull = true로 업데이트
    - 버튼의 v-bind 지시자에 따라 버튼이 disabled 상태로 변경
    - 버튼에 .disabled CSS 클래스가 추가 (비활성화 디자인 적용)
    2) 출력 데이터가 더 이상 없으므로 ‘List items are fully loaded!’ alert 노출
    - 만약 API에서 추가로 호출할 데이터가 있는 경우 Axios로 추가 데이터를 요청 후 newsAll 객체를 업데이트 하도록 코드를 추가하면 됩니다.

지금까지 Vue.js SPA 튜토리얼 핵심 기능 구현에 대해 다뤄보았습니다.
그 밖에 추가로 구현해볼 수 있는 부가 기능들은 다음과 같습니다.

0. 공통
- 데이터 로딩 오버레이 (Spinner) 적용
- 사용자 메시지 토스트 팝업 적용

1. LIVE PRICES
- 암호 화폐 가격 1분 단위 업데이트 적용
- 업데이트 시간 출력 (타이틀 우측)
- 60초 타이머 출력 (화면 좌/상단)
- 업데이트된 가격 셀에 특정 배경색 적용 (fadeIn/fadeOut)
- 특정 암호화폐 셀을 선택하면 차트로 이동
(ex: https://cryptowat.ch/markets/bithumb/btc/krw)

2. RECENT NEWS
- 뉴스 기사 10분 단위 업데이트 적용
- 업데이트 시간 출력 (타이틀 우측)
- 영/한 <> 한/영 번역 적용

완성된 결과물은 http://fe.hivelab.co.kr/spa 페이지에서 확인할 수 있습니다.

[Vue.js] SPA 튜토리얼 — Part1
프로젝트 세팅, Axios를 활용한 API 데이터 호출 — Price

[Vue.js] SPA 튜토리얼 — Part2
Axios를 활용한 API 데이터 호출- Ratio, News

[▣] [Vue.js] SPA 튜토리얼 — Part3
News 데이터 컨트롤 — More 버튼

🔍 하이브랩과 함께 할 멋진 FE개발자를 찾고 있습니다.

--

--