昨天把元件溝通規範統一後,今天我也沒有急著加新功能,而是把整個 App 的起跑順序做理清,在正確時機載入資料、加上 Skeleton 骨架、把語言/主題/任務的「三線同步」拉直。
為什麼要調整初始化順序?之前偶爾會遇到這些小狀況:重整瞬間畫面閃白、語言切不動、主題先跳再回、清單短暫消失又冒回來,原因其實都一樣,載入的先後有點亂,有的資料來自 localStorage,有的受 i18n 控制,還有 UI 會受 data-theme 影響。只要有一條線搶跑或慢半拍,就會看到「抖一下」的視覺雜訊,因此,我把「起跑步驟」排成這樣:
2.顯示骨架:在資料到位前,讓使用者看到淡淡的雛形,不是空白。
3.解除骨架:資料與設定都就緒,才真正渲染主畫面。
4.後續同步:
a.watch(locale) ↔ watch(lang) 互相對齊,避免「切到一半又被改回去」。
b.watch(theme) 即時更新 data-theme。
c.watch(tasks, { deep: true }) 寫回 localStorage,讓重整後還在。
三線同步:語言、主題、任務
a.語言(i18n):使用全域 composer,locale 與 localStorage('lang') 互相 watch,同步 <html lang>。同時做了代碼正規化(zh-TW / en-US),避免 UI 發出「中文」或「English」這種非標準值造成切不動。
b.主題(Theme): 一律以 data-theme 控制外觀,ThemeToggle 只負責改變 ref,實際套用集中在 applyTheme(),單一出口好維護。
c.任務(Tasks): 載入時用 parseTasks() 做格式檢查(必須有 id/title/done),避免壞資料把 App 弄掛;寫回時用 watch(..., { deep: true })。為了更穩,我也準備了去重邏輯與輕量節流(可選,文末備註)。
不只這樣今天我也有做介面的微調,希望一步步邁向更清楚的資訊區位發展,今天最終畫面長這樣: