Product & Design • July 6, 2026

設計 Daily Tomato Todo:當待辦清單和計時器是同一個產品

設計 Daily Tomato Todo:當待辦清單和計時器是同一個產品

設計 Daily Tomato Todo:當待辦清單和計時器是同一個產品

多數待辦 app 把時間當成標籤、把專注當成附加功能:任務堆在一條無盡的清單裡,蕃茄鐘則縮在你不會看的角落。Daily Tomato Todo 是一個 Vue 3 + Pinia 的每日計畫工具,建立在不同的前提上——「按天計畫」和「專注做一件事」應該是同一個動作,而不是兩個分開的 app。

你可以直接使用線上版,程式碼在 GitHub。這篇文章是它背後的設計故事。


問題:一條無盡的清單,一個被忽略的計時器

單一捲動清單回答的是「我有什麼要做?」,卻永遠回答不了「我今天在做什麼?」。而釘在畫面角落的計時器,反而在跟它本該讓你安靜下來的那份清單搶注意力。設計問題從來不是「怎麼加一個蕃茄鐘功能?」,而是「當日子、任務、專注時段是同一個物件時,這個 app 長什麼樣子?」

撐起整個設計的四個決策

整個 app 掛在四個決策上。每一個不是少一次點擊,就是少一個干擾。

1. 行事曆藏在標題日期後面

不新增按鈕。使用者本來就會看的大日期直接變成入口:點一下,整個月往下展開。每格下方的小圓點是狀態摘要——未完成、逾期、全部完成——而且每一天都可以點,沒任務的日子只是顯示淡一點。點任何一天,畫面就滑過去,隨時可以新增任務。

2. 日期 chip 跟著你正在看的那天

輸入框帶著一顆日期 chip,預設值永遠是目前檢視中的那一天。在「明天」的卡片上打字,建的就是明天的任務——最常見的情境完全不用多點。點 chip 會展開快速選項(今天、明天、下週一)和完整的日期選擇器。

3. 一天一張卡,滑動移動

清單是一條水平的每日卡片軌道,用純 CSS scroll-snap 實作——零依賴、原生慣性手感、天數可無限往前後生成。上方的日子膠囊跟著捲動位置亮起,離開今天時出現「回今天」捷徑。篩選作用在你所在的那張卡片,而不是某鍋全域大雜燴。

4. 蕃茄鐘一開始就接管全畫面

按下任務的播放鍵,專注遮罩蓋住一切:倒數、進度環、任務名稱、暫停與停止。你不能滑清單,不能加任務。**防分心是功能,不是限制。**蕃茄結束後,休息畫面以較平靜的綠色接手,結束再把你交還給清單。

那些無聊但重要的決定

三個小小的產品決策定義了資料模型:

  • **沒選日期的任務歸到今天。**一條簡單規則,勝過一個使用者得記得去看的「未排程」分類。
  • **未完成的任務不自動滾動。**它們留在原本的日子,作為誠實的紀錄;今天的卡片頂端出現紅色提示,一鍵移過來。歷史保持真實,修正保持便宜。
  • **截止日和排程日是同一個概念。**個人待辦事項上放兩個日期欄位,是資料模型在自找問題。

實作:小 app,真架構

  • **Vue 3 + Pinia,單一 store。**輪播的捲動位置、標題日期、日子膠囊、行事曆選取,全部讀寫同一個 store——兄弟元件之間沒有事件義大利麵。
  • **行事曆圓點是衍生狀態。**未完成、逾期、全部完成的標記,從渲染卡片的同一個 store 計算出來,摘要永遠不可能跟明細打架。
  • **蕃茄鐘是一個狀態機。**idle、focus、paused、break——以全畫面遮罩加 SVG 進度環呈現。把「暫停」明確建模(而不是 hack 那個 interval),是遮罩值得信任的原因。
  • **零依賴輪播。**CSS scroll-snap 免費給你原生的滑動物理,捲動監聽只做索引計算。

為什麼有效

這個專案幾年前是我學 Vue 的第一個練習。用 Vue 3 和 Pinia 重建它,是一次刻意的節制練習:最大膽的功能是那個拿走選項而不是增加選項的功能,最聰明的程式碼是那段被刪掉、換成一個 CSS 屬性的程式碼。小產品,真的產品思維。

👉 打開線上版 →,按下任一任務的播放鍵,感受全畫面的專注模式。