2025-03-06-天氣查詢應用程式」的第 2 步:畫面顯示三個城市的主要天氣資訊
第 2 步:畫面顯示三個城市的主要天氣資訊。
✅ 規格說明(第 2 步)
畫面要顯示三筆資料,每筆為一個城市,並顯示以下資訊:
- 城市名稱
locationName
- 天氣現象(
Wx
)→ 顯示今天天氣
- 最高溫度(
MaxT
)
- 最低溫度(
MinT
)
- 降雨機率(
PoP
)
每個城市一塊區塊,直向排列三排。
✅ 完整範例程式碼(Vue 3 + Composition 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 49 50 51 52
| <template> <h2>🌦️ 三個城市的天氣概況</h2>
<div v-for="city in weatherData" :key="city.locationName" class="city-card"> <h3>{{ city.locationName }}</h3> <p>🌤️ 天氣現象:{{ getWeatherElement(city, 'Wx') }}</p> <p>🌡️ 最高溫度:{{ getWeatherElement(city, 'MaxT') }}°C</p> <p>🥶 最低溫度:{{ getWeatherElement(city, 'MinT') }}°C</p> <p>☔ 降雨機率:{{ getWeatherElement(city, 'PoP') }}%</p> </div> </template>
<script setup> import { ref, onMounted } from 'vue'
const apiKey = '你的 API 金鑰' const url = `https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=${apiKey}`
const allCities = ['臺北市', '臺中市', '高雄市'] const weatherData = ref([])
onMounted(async () => { try { const response = await fetch(url) const data = await response.json()
const locations = data.records.location
weatherData.value = locations.filter(loc => allCities.includes(loc.locationName) ) } catch (error) { console.error('❌ 發生錯誤:', error) } })
// 取得指定欄位的第一筆預報值 function getWeatherElement(city, elementName) { const element = city.weatherElement.find(el => el.elementName === elementName) return element?.time[0]?.parameter?.parameterName || 'N/A' } </script>
<style scoped> .city-card { border: 1px solid #ccc; padding: 1rem; margin: 1rem 0; border-radius: 0.5rem; background: #f0f8ff; } </style>
|
🔍 說明重點
欄位 |
說明 |
Wx |
天氣現象,如「晴時多雲」 |
PoP |
降雨機率(百分比) |
MaxT |
最高溫度(攝氏) |
MinT |
最低溫度(攝氏) |
.time[0] |
代表第一個時間區段(通常是今晚~明晨) |
✅ 下一步可選:
- 💡 加上
<select>
選擇城市、只顯示單一城市資料
- 💡 做出 RWD + 背景色變化
- 💡 根據天氣現象改變 icon 或背景
你可以先跑跑看這個範例,再來決定是否繼續加入 RWD 或互動選單功能,我可以帶你一步步來 💪
好問題!你問的:
畫面並沒有直向排列,是不是因為沒有指定 border-box
?
其實不是關鍵問題在 border-box
,而是:
✅ 【畫面沒直向排列】常見 3 個可能原因:
✅ 1. 最外層容器是否有 display: flex; flex-direction: column;
在 <style scoped>
裡應該這樣寫:
1 2 3 4 5
| .weather-container { display: flex; flex-direction: column; gap: 1.5rem; }
|
✅ 2. 確定 .weather-container
是否有套上 class?
你的 <template>
裡應該是:
1 2 3 4 5
| <div class="weather-container"> <div v-for="city in weatherData" :key="city.locationName" class="city-card"> ... </div> </div>
|
✅ 別漏掉 class="weather-container"
!
這是讓容器用 flex 垂直排列的關鍵。
✅ 3. 不是 border-box
問題(它是內容區域的計算方式)
box-sizing: border-box;
影響的是:padding + border 是否會被算進寬度
- 跟「排列方向」沒關係,和
flex-direction
不同概念
🔧 快速檢查步驟:
- 檢查
weather-container
是否真的有 flex-direction: column
- 確保有套到 class
- 確保畫面寬度夠寬(手機版可能看不出差別)
- 開 DevTools → 點
.weather-container
→ 看 computed style 有沒有 display: flex
bonus:想強制直向排列
你可以加這行來幫助確認效果:
1 2 3 4 5
| .weather-container { display: flex; flex-direction: column; border: 2px dashed red; }
|