🚫 Ad Blocker Detected

Please disable your AD blocker to continue using this site. Ads help us keep the content free! please press keyboard F5 to refresh page after disabled AD blocker

請關閉廣告攔截器以繼續使用本網站。廣告有助於我們保證內容免費。謝謝! 關閉後請按 F5 刷新頁面

0%

串接 Restcountries By Vue.js

前文

最近面試有一間公司要求使用Restcountries API使用CRUD前端Html串接API,有看我文章的夥伴應該知道我大多是研究後端或CI/CD相關技術,對於前端技術較少研究,這次我打算使用vue.js來完成此次需求.

需求如下

  1. 分頁
  2. 顯示國家相關資訊
  3. 排序效果
  4. 點選國家名稱進入Detail頁面

因為以上幾點都是CRUD相關操作,關於CRUD相關操作使用三大框架就很適合(所以我選擇使用Vue)

話不多說先給大家看看成品 RestcountriesSample

Source Code

要使用的API介紹

雖然官網對於API介紹雖少,但我相信只要有常串API的人應該可以很快猜出每個API作用.

  • All:請求所有國家資訊
  • FULL NAME:查找國家By名子.

而且我發現大部分API都可以用GET來請求.

只要用這兩個就可以完成我們的需求

Code解說與問題分析

一開始我在分析問題是要找尋合適的API後面經過塞選挑出上面兩個API.

接下來我就考慮把畫面用Table + 分頁方式呈現,而Detail Page利用Query String方式傳Country Name來看明細資料.

我用Pure前端串接API,所以我建立兩個Html頁面

  • 一個是Master Page
  • 一個是Detail Page

Master page

在Javascript code我主要介紹流程

主要在一開始頁面建立時去Load All 資料並把資料binding在rows陣列物件

orderBy方法,提供一個排序實現這邊可以讓Page呼叫時傳入要排的欄位名稱就可以不用HardCode(使用類似@click="orderBy('name'),ASC *= -1")傳入Name就可以對於Name來排序,提高程式碼可用性

因為API請求有時候會比較久,所以我這邊使用vue-loading-overlay來當Loading Page(有興趣的可以在查閱此連結的API)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<div id="app">
<template>
<div class="vld-parent">
<loading :active.sync="isLoading" :is-full-page="true"></loading>
</div>
</template>
<div><b>Search Country Name:</b> <input type="text" v-model="countryName"></div>
<div v-if="filteredRows.length === 0">No Data Display!!</div>
<table v-if="filteredRows.length > 0" class="table table-condensed">
<thead>
<tr>
<th>國旗</th>
<th @click="orderBy('name'),ASC *= -1">國家名稱
<span class="icon" :class="{'Reverse':ASC==1}">
<i class="fa fa-angle-up"></i>
</span>
</th>
<th>2位國家代碼</th>
<th>3位國家代碼</th>
<th>母語名稱</th>
<th>替代國家名稱</th>
<th>國際電話區號</th>
</tr>
</thead>
<tr v-for="item in filteredRows.slice(pageStart, pageStart + pageSize)">
<td><img v-bind:src=item.flag style='height:150px'></td>
<td>
<a target="_blank" :href="'./CountryModel.html?countryName=' + item.name">
{{ item.name }}
</a>
</td>
<td>{{ item.alpha2Code }}</td>
<td>{{ item.alpha3Code }}</td>
<td>{{ item.nativeName }}</td>
<td>{{ item.altSpellings[0] }}</td>
<td>{{ item.callingCodes[0] }}</td>
</tr>
</table>
<div class="pagination">
<ul>
<li v-bind:class="{'disabled': (currPage === 1)}" @click.prevent="setPage(currPage-1)"><a href="#">Prev</a></li>
<li v-for="n in totalPage" v-bind:class="{'active': (currPage === (n))}" @click.prevent="setPage(n)"><a
href="#">{{n}}</a></li>
<li v-bind:class="{'disabled': (currPage === totalPage || totalPage === 0)}"
@click.prevent="setPage(currPage+1)"><a href="#">Next</a></li>
</ul>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
var app = new Vue({
el: '#app',
data: {
rows: [],
pageSize: 25,
currPage: 1,
countryName: '',
ASC: 1,
isLoading: true
},
computed: {
filteredRows: function () {
var self = this;
return self.rows.filter(x=> !self.countryName || x.name.search(self.countryName) != -1);
},
pageStart: function () {
return (this.currPage - 1) * this.pageSize;
},
totalPage: function () {
return Math.ceil(this.filteredRows.length / this.pageSize);
}
},
methods: {
setPage: function (index) {
if (index <= 0 || index > this.totalPage) {
return;
}
this.currPage = index;
},
orderBy: function (item) {
var self = this;
return self.rows.sort(function (obj1, obj2) {
var obj1 = obj1[item]
var obj2 = obj2[item]

if (obj1 === obj2)
return 0;
else if (obj1 > obj2)
return self.ASC;
else
return self.ASC * -1;
});
}
},
created: function () {
var self = this;
$.get('https://restcountries.eu/rest/v2/all', function (data) {
self.rows = data;
self.isLoading = false;
});
},
watch:{
countryName:function(newValue){
this.currPage = 1;
}
}
});

Detail Page

Detail我使用FULL NAME來查找我要的國家明細

Detail Html畫面,我就不多說可以看原始碼

因為我在設計時想要使用QueryString來傳送CountryName,所以我利用URLSearchParams來取得QueryString countryName資料並使用Ajax查詢API

如果查不到資料或使用者傳送一個不存在的資訊,我就會顯示No Data Display!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var app = new Vue({
el: '#app',
data: {
vm: {},
isLoading : true
},
created: function () {
var self = this;
let urlParams = new URLSearchParams(window.location.search);
var countryName = urlParams.has('countryName') ? urlParams.get('countryName') : '';
var url = 'https://restcountries.eu/rest/v2/name/'+encodeURI(countryName)+'?fullText=true'
$.get(url, function (data) {
self.vm = data[0];
self.isLoading = false;
}).fail(function() {
document.write('No Data Display!!');
});
}
});

小結

這次題目我前後大約花半天就把東西從無到有完成,個人覺得還算蠻順利的,但我寫的Front Code可能不太標準(因為我很少寫Js XDD)

如果有寫得不好的地方在歡迎指教

不得不說我覺得Vuejs寫起來真的蠻直覺,而且很多資源可以查閱學習來相對蠻容易的

相是Loading Page就有很多不同的樣式可以挑選.

__此文作者__:Daniel Shih(石頭)
__此文地址__: https://isdaniel.github.io/vue-first-Restcountries/
__版權聲明__:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!

如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^