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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| <script setup> import { ref, watch, computed } from 'vue'
const cities = ['臺北市', '新北市', '桃園市', '臺中市', '臺南市', '高雄市'] const selectedCity = ref('臺北市') const weatherInfo = ref(null)
const fetchWeather = async () => { const apiKey = '你的 API KEY' const url = `https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=${apiKey}&locationName=${selectedCity.value}`
try { const res = await fetch(url) const data = await res.json() const location = data.records.location[0] const elements = location.weatherElement
weatherInfo.value = { description: elements[0].time[0].parameter.parameterName, minTemp: elements[2].time[0].parameter.parameterName, maxTemp: elements[4].time[0].parameter.parameterName, rain: elements[1].time[0].parameter.parameterName } } catch (error) { console.error('API 錯誤:', error) } }
// 監聽縣市變化 watch(selectedCity, fetchWeather) fetchWeather()
// 根據天氣現象設定背景類別 const backgroundClass = computed(() => { if (!weatherInfo.value) return 'bg-default'
const desc = weatherInfo.value.description if (desc.includes('雷') || desc.includes('雨')) return 'bg-thunder' if (desc.includes('陰')) return 'bg-cloudy' if (desc.includes('晴')) return 'bg-sunny' return 'bg-default' }) </script>
<template> <div :class="['weather-container', backgroundClass]"> <div class="weather-card"> <h2>天氣查詢</h2> <label> 縣市: <select v-model="selectedCity"> <option v-for="city in cities" :key="city" :value="city">{{ city }}</option> </select> </label>
<div v-if="weatherInfo" class="weather-data"> <p>🌦️ 現象:{{ weatherInfo.description }}</p> <p>🔺 最高溫:{{ weatherInfo.maxTemp }}°C</p> <p>🔻 最低溫:{{ weatherInfo.minTemp }}°C</p> <p>🌧️ 降雨率:{{ weatherInfo.rain }}%</p> </div> </div> </div> </template>
<style scoped> .weather-container { min-height: 100vh; display: flex; justify-content: center; align-items: center; transition: background 0.5s ease-in-out; padding: 1rem; }
/* 背景樣式 */ .bg-sunny { background: linear-gradient(to bottom, #87CEFA, #ffffff); } .bg-cloudy { background: linear-gradient(to bottom, #999, #ccc); } .bg-thunder { background: linear-gradient(to bottom, #111, #444); animation: flash 2s infinite; } .bg-default { background: #eee; }
/* 閃電效果 */ @keyframes flash { 0%, 100% { background-color: #111; } 50% { background-color: #222; } }
.weather-card { background: white; padding: 2rem; border-radius: 1rem; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); max-width: 400px; width: 100%; text-align: center; }
/* RWD 響應式設計 */ @media (max-width: 600px) { .weather-card { padding: 1rem; } h2 { font-size: 1.4rem; } } </style>
|