2025-01-17 JavaScript 系列八:第4課 ── 行事曆應用程式-步驟07
正統 Vue 3 的做法
太棒了!🥳
你說【要】,那我來幫你整理成一版 「完整版、糾正後、超乾淨、專業版」 ✨
這版會修掉你所有小問題,而且讓你的 Vue 程式更乾淨。
🔥【完整版修正版】🔥
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
| <template> <div> <h2>我的行事曆</h2> <div ref="calendarRef" id="calendar"></div> </div>
<!-- 新增活動的表單 Modal --> <div v-if="showForm" class="modal-overlay"> <div class="modal"> <h3>新增活動</h3> <label> 活動名稱: <input v-model="formData.title" type="text"> </label> <label> 活動日期: <input v-model="formData.date" type="date"> </label> <label> 活動時間: <input v-model="formData.time" type="time"> </label> <div class="modal-buttons"> <button @click="saveEvent">儲存</button> <button @click="showForm = false">取消</button> </div> </div> </div> </template>
<script setup> import { ref, onMounted } from 'vue'
const calendarRef = ref(null) const showForm = ref(false) const formData = ref({ title: '', date: '', time: '' })
let calendar = null // 👈 這裡設全域變數,不要再用 window
onMounted(() => { if (window.FullCalendar && window.FullCalendar.Calendar) { calendar = new window.FullCalendar.Calendar(calendarRef.value, { initialView: 'dayGridMonth', locale: 'zh-tw', events: [], dateClick(info) { // 移除所有舊的按鈕 document.querySelectorAll('.add-event-button').forEach(btn => btn.remove())
// 移除舊的灰色背景 document.querySelectorAll('.selected-day').forEach(el => { el.classList.remove('selected-day') })
const cellEl = info.dayEl.querySelector('.fc-daygrid-day-frame') if (!cellEl) return
// ✅ 加背景色 class cellEl.classList.add('selected-day')
// ✅ 新增按鈕 const button = document.createElement('button') button.className = 'add-event-button' button.innerHTML = `<span class="text">新增活動</span><span class="icon">➕</span>`
button.onclick = () => { formData.value.date = info.dateStr formData.value.time = '09:00' formData.value.title = '' showForm.value = true }
cellEl.appendChild(button) } }) calendar.render() } else { console.error('FullCalendar 尚未載入,請確認 CDN script') } })
function saveEvent() { if (!formData.value.title) { alert('請輸入活動名稱') return }
const event = { title: formData.value.title, start: `${formData.value.date}T${formData.value.time}` }
// ✅ 直接用 calendar.addEvent,不要掛到 window calendar.addEvent(event)
showForm.value = false } </script>
<style scoped> #calendar { max-width: 800px; margin: 20px auto; }
/* ✅ 點選日期格背景變淺灰色 */ :deep(.selected-day) { background-color: #f0f0f0 !important; transition: background-color 0.3s ease; }
/* ✅ 新增活動按鈕基本樣式 */ :deep(.add-event-button) { background-color: #1e2b37; color: white; border: none; padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer; display: flex; align-items: center; gap: 4px; }
/* ✅ 桌機版:顯示文字+icon */ :deep(.add-event-button .icon) { display: none; }
:deep(.add-event-button .text) { display: inline; }
/* ✅ 手機版 RWD:只顯示 icon */ @media (max-width: 600px) { :deep(.add-event-button .text) { display: none; } :deep(.add-event-button .icon) { display: inline; font-size: 16px; } }
/* ✅ Modal 樣式 */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 999; }
.modal { background: white; padding: 20px; border-radius: 8px; width: 90%; max-width: 300px; }
.modal label { display: block; margin-bottom: 10px; }
.modal input { width: 100%; padding: 4px; box-sizing: border-box; }
.modal-buttons { display: flex; justify-content: space-between; margin-top: 15px; } </style>
|
🎯這版有什麼改進?
原本 |
現在 |
window.addEventToCalendar (外洩全域) |
直接使用 calendar 變數 |
caldar 打錯 |
正確是 calendar |
window 掛方法,不乾淨 |
全部留在 script setup 裡管理 |
小細節錯誤 |
全部校正 & 專業化 |
✅ 現在這版效果
- 點日期 ➡️ 出現淺灰色
- 自動出現「新增活動」按鈕
- 按下「新增活動」➡️ 彈出輸入表單
- 儲存後 ➡️ 活動直接顯示在該格子裡
- 手機版按鈕自動變成小圖示 (RWD OK)
要不要我也順便教你:
- 怎麼加「編輯活動」?
- 怎麼加「刪除活動」?
- 或是「活動列表」管理?
要的話跟我說【繼續升級】,我可以帶你一步一步進階~🚀✨
要嗎?要的話回我【繼續升級】!🌟