2025-03-09-天氣查詢應用程式」的自製 Checkbox 多選 UI

2025-03-09-天氣查詢應用程式」的自製 Checkbox 多選 UI

這裡是 ✅自製 Checkbox 多選 UI 的完整範例:


✅ 功能特色:

  • 多選城市(不限數量)
  • 自製 checkbox,不需額外安裝套件
  • 適合手機 & 電腦點選
  • 動態顯示選擇的城市天氣資訊

✅ Vue 3 完整範例:

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
<template>
<h2>🌦️ 自製 Checkbox 選城市</h2>

<div class="checkbox-list">
<label v-for="city in sortedCityNames" :key="city" class="checkbox-item">
<input type="checkbox" :value="city" v-model="selectedCities" />
{{ city }}
</label>
</div>

<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 = '你的APIKey' // 換成你自己的
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 res = await fetch(url)
const data = await res.json()
const locations = data.records.location
weatherData.value = locations
allCityNames.value = locations.map(loc => loc.locationName)
} catch (err) {
console.error('❌ 發生錯誤:', err)
}
})

// 中文排序
const sortedCityNames = computed(() =>
[...allCityNames.value].sort((a, b) => a.localeCompare(b, 'zh-Hant'))
)

// 顯示被選取城市的天氣
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>
.checkbox-list {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-bottom: 1rem;
}
.checkbox-item {
display: flex;
align-items: center;
gap: 0.25rem;
background: #eaf6ff;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
cursor: pointer;
user-select: none;
}

input[type='checkbox'] {
transform: scale(1.2);
}

.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>

🧠 為什麼適合手機?

  • 不需 Ctrl / Command
  • 點一下就能勾選/取消
  • UI 可客製化成按鈕風格、Tag 樣式等

// 🌟 用官方排序對資料排序
const officialCityOrder = [
‘臺北市’, ‘新北市’, ‘桃園市’, ‘臺中市’, ‘臺南市’, ‘高雄市’,
‘基隆市’, ‘新竹縣’, ‘新竹市’, ‘苗栗縣’, ‘彰化縣’,
‘南投縣’, ‘雲林縣’, ‘嘉義縣’, ‘嘉義市’, ‘屏東縣’,
‘宜蘭縣’, ‘花蓮縣’, ‘臺東縣’,
‘澎湖縣’, ‘金門縣’, ‘連江縣’
]