今天來到另一個重頭戲,就是接open api拿到實際的天氣資料,我們選用的是這個api:
https://works.ioa.tw/weather/api/doc/index.html
在開始之前,大家應該都已經刻好畫面了,如果還沒的也沒關係,可以直接用我這個commit的程式碼:
https://github.com/yuanchen1103/2020ironman-weather/commit/493e73e6f7c59e7481cc28bcb6f7c6bdc420ec4a
在順序上,我們會先用第一個api**「取得所有縣市鄉鎮」**來拿到縣市資料,在拿回來的資料當中我們就能拿到城市的id與名字,整理好以後放到左上角那個dropdown selector裡面。
GET https://works.ioa.tw/weather/api/all.json
在這邊我們統一從App.vue中fetch資料,再以props傳下去各個component裡面。
在methods當中創立一個getCityData()
的function,把拿到的response存到data當中,並在created的時候執行他,我們的Select就能直接使用這個array。
getCityData() {
axios
.get('https://works.ioa.tw/weather/api/all.json')
.then(response => {
this.cityData = response.data.map(city => ({ label: `${city.name}, 台灣`, value: city.id }));
})
.catch(error => {
// eslint-disable-next-line
console.error(error);
});
}
created() {
this.getCityData();
},
在拿到每個城市id以後,我們能watch被選中的城市id,若有變動就執行拿天氣的getWeatherData()
:
GET https://works.ioa.tw/weather/api/weathers/:id.json
getWeatherData(id) {
axios
.get(`https://works.ioa.tw/weather/api/weathers/${id}.json`)
.then(response => {
this.weatherData = response.data;
})
.catch(error => {
// eslint-disable-next-line
console.error(error);
});
}
watch: {
selected() {
this.getWeatherData(this.selected.value);
}
},
接下來就是整理拿到的資料,我們把計算的資料放在computed裡面,這樣如果data有變,計算的結果也會跟著變,然後把結果用prop傳進去component裡面就完成囉。(最近都沒下雨,所以雨量資料都是0 XD)
// 雨量資料
getRainfallData() {
const { histories } = this.weatherData;
return histories.map(item => ({
name: moment(item.at).format('mm:ss'),
value: item.rainfall
}));
},
// 溫度資料
getTempChartData() {
const { histories } = this.weatherData;
return histories.map(item => ({
name: moment(item.at).format('mm:ss'),
value: item.temperature
}));
},
// 體感溫度資料
getFeltAirChartData() {
const { histories } = this.weatherData;
return histories.map(item => ({
name: moment(item.at).format('mm:ss'),
value: item.felt_air_temp
}));
},
// 濕度資料
getHumidityChartData() {
const { histories } = this.weatherData;
return histories.map(item => ({
name: moment(item.at).format('mm:ss'),
value: item.humidity
}));
},
// 平均溫度
getAvgTemp() {
const { histories } = this.weatherData;
return (sum(histories.map(item => item.temperature)) / histories.length).toFixed(1);
},
// 平均體感溫度
getAvgFeltAir() {
const { histories } = this.weatherData;
return (sum(histories.map(item => item.felt_air_temp)) / histories.length).toFixed(1);
},
// 平均濕度
getAvgHumidity() {
const { histories } = this.weatherData;
return (sum(histories.map(item => item.humidity)) / histories.length).toFixed(1);
}
<div class="row">
<LineChartBlock title="Temperature"
color="#00BAB6"
:icon="temp"
:chartData="getTempChartData"
:avg="getAvgTemp" />
<LineChartBlock title="Felt Air"
color="#94BF41"
:icon="snow"
:chartData="getFeltAirChartData"
:avg="getAvgFeltAir" />
<LineChartBlock title="Humidity"
color="#F8B904"
:icon="water"
:chartData="getHumidityChartData"
:avg="getAvgHumidity" />
</div>
<div class="row"
style="margin-top: 40px;">
<RainfallBlock :chartData="getRainfallData" />
<SunBlock :sunset="getSun.sunset" :sunrise="getSun.sunrise"/>
</div>
這樣我們的專案就大功告成囉~另外可以針對還在fetching時加上loading動畫,增加使用者體驗。明天將會教大家把完成的專案架到firebase上。