20250307-天氣查詢應用程式」的第 3 步:自由選擇三個城市
你現在的程式其實已經能顯示三個城市的天氣了(臺北市、臺中市、高雄市),因為你用這行篩選了資料:
1
| const allCities = ['臺北市', '臺中市', '高雄市']
|
✅ 下一步目標(你說的「可以一次選三個城市」):
你想讓使用者「自由選擇三個城市」,而不是程式寫死三個城市名稱。
✅ 修改目標:
讓使用者從城市下拉選單中選擇三個城市,並顯示它們的天氣資訊。
✅ 第一步:新增一個多選下拉選單
1 2 3
| <select multiple v-model="selectedCities"> <option v-for="city in allCityNames" :key="city">{{ city }}</option> </select>
|
✅ 完整程式碼(支援自由選三城市)
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| <template> <h2>🌦️ 自選三個城市天氣概況</h2>
<!-- 多選城市 --> <label>選擇最多三個城市:</label> <select multiple v-model="selectedCities"> <option v-for="city in allCityNames" :key="city">{{ city }}</option> </select> <p>目前選擇:{{ selectedCities.join(', ') }}</p>
<div class="weather-container"> <div v-for="city in filteredWeatherData" :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> </div> </template>
<script setup> import { ref, computed, onMounted } from 'vue'
const apiKey = '你的 CWA API Key' // 請替換成你的 key const url = `https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=${apiKey}`
const weatherData = ref([]) const allCityNames = ref([]) const selectedCities = ref([])
onMounted(async () => { try { const response = await fetch(url) const data = await response.json() const locations = data.records.location
weatherData.value = locations allCityNames.value = locations.map(loc => loc.locationName)
// 預設三個城市 selectedCities.value = ['臺北市', '臺中市', '高雄市'] } catch (error) { console.error('❌ 發生錯誤:', error) } })
const filteredWeatherData = computed(() => weatherData.value.filter(city => selectedCities.value.includes(city.locationName)) )
function getWeatherElement(city, elementName) { const element = city.weatherElement.find(el => el.elementName === elementName) return element?.time[0]?.parameter?.parameterName || 'N/A' } </script>
<style scoped> select { width: 100%; padding: 0.5rem; margin-bottom: 1rem; font-size: 1rem; }
.weather-container { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.city-card { flex: 1 1 300px; max-width: 300px; background: #f0f8ff; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border-left: 6px solid #3498db; } </style>
|
✅ Bonus 小提醒:限制最多選三個城市(進階)
你可以加入檢查邏輯,限制使用者最多只能選三個城市,有需要我可以幫你加上這段邏輯。
需要我幫你加「限制只能選三個城市」或「根據天氣變化變色背景」嗎?👀
好的!以下是加上「最多只能選三個城市」的版本 ✅
當使用者選超過三個時,會自動移除最後選的那個,並顯示警告。
✅ 完整程式碼:限制選最多三個城市
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| <template> <h2>🌦️ 自選三個城市天氣概況</h2>
<!-- 多選城市 --> <label>請選擇最多三個城市:</label> <select multiple v-model="selectedCities" @change="checkLimit"> <option v-for="city in allCityNames" :key="city">{{ city }}</option> </select> <p>目前選擇:{{ selectedCities.join(', ') }}</p> <p v-if="limitReached" style="color: red;">⚠️ 最多只能選三個城市</p>
<div class="weather-container"> <div v-for="city in filteredWeatherData" :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> </div> </template>
<script setup> import { ref, computed, onMounted } from 'vue'
const apiKey = '你的 CWA API Key' // 請換成你的 const url = `https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=${apiKey}`
const weatherData = ref([]) const allCityNames = ref([]) const selectedCities = ref([]) const limitReached = ref(false)
onMounted(async () => { try { const response = await fetch(url) const data = await response.json() const locations = data.records.location
weatherData.value = locations allCityNames.value = locations.map(loc => loc.locationName)
// 預設三個城市 selectedCities.value = ['臺北市', '臺中市', '高雄市'] } catch (error) { console.error('❌ 發生錯誤:', error) } })
// ✅ 限制最多三個城市 function checkLimit() { if (selectedCities.value.length > 3) { selectedCities.value.pop() // 移除最後選的 limitReached.value = true setTimeout(() => { limitReached.value = false }, 2000) } }
const filteredWeatherData = computed(() => weatherData.value.filter(city => selectedCities.value.includes(city.locationName)) )
function getWeatherElement(city, elementName) { const element = city.weatherElement.find(el => el.elementName === elementName) return element?.time[0]?.parameter?.parameterName || 'N/A' } </script>
<style scoped> select { width: 100%; padding: 0.5rem; margin-bottom: 0.5rem; font-size: 1rem; }
.weather-container { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.city-card { flex: 1 1 300px; max-width: 300px; background: #f0f8ff; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border-left: 6px solid #3498db; } </style>
|
🧠 重點說明:
部分 |
說明 |
@change="checkLimit" |
每次下拉選單變動時,觸發檢查 |
selectedCities.value.pop() |
超過 3 個,就把最後選的移除 |
limitReached |
用來控制是否顯示警告訊息 |
你可以自己試著把 3
改成 2
或 5
看會發生什麼~