行動練習:和 Claude 做一個待辦清單網頁
把整個單元串起來:從一個空資料夾開始,用需求說明書描述想要的網頁,在 Plan 模式下和 Claude 對齊計畫,讓它寫出一個會記住資料的待辦清單,再一輪一輪改進,每一輪都用 Git 存檔。
這堂課要做什麼
這是本單元的最後一堂。前面六堂,你學會了:
- 安裝和啟動 Claude Code(第 2 堂)
- 在對的資料夾工作、寫 CLAUDE.md(第 3 堂)
- 挑一個順手的介面(第 4 堂)
- 用 Plan 和 Manual 模式安全地讓它動手(第 5 堂)
- 用 Git 存檔,改壞了也能回來(第 6 堂)
今天要把這些全部用上,做出一個真的能用的待辦清單網頁:可以新增、打勾、刪除、篩選,而且關掉瀏覽器再打開,清單還在。
整個網頁只有一個檔案 index.html,裡面裝著這四個零件。
你不需要看懂所有程式碼。這堂課的重點是工作流程:怎麼描述、怎麼審核、怎麼試用、怎麼一輪一輪變好。
第 0 步:準備工作區
開一個新資料夾,不要和之前的學習筆記混在一起:
mkdir todo-app
cd todo-app
claude
用 VS Code 的話,選「檔案」→「開啟資料夾」打開 todo-app,再打開 Claude 面板。用桌面 App 的話,在 Code 分頁選這個資料夾。
確認現在是 Manual 模式(第 5 堂教過怎麼看),然後送出:
這是一個新專案,我要做一個待辦清單網頁。請幫我:
- 執行 git init。
- 建立 CLAUDE.md,內容包含:
- 專案說明:一個單一檔案的待辦清單網頁,用 HTML、CSS、JavaScript 寫成,不使用任何外部套件。
- 與我合作的方式:一律用繁體中文;我是新手,解釋用白話;改檔案前先說明要改什麼。
- 做第一次 commit,說明寫「建立專案」。
逐一看過它要執行的指令,同意之後,你就有了一個乾淨的起點。
第 1 步:寫需求說明書
還記得「AI 寫程式入門」裡的需求說明書嗎?給 AI 的需求越清楚,第一版就越接近你要的。一份好的說明書包含四個部分:目標、功能、限制、怎樣算完成。
先切到 Plan 模式(Shift+Tab 或模式選單),再送出:
/plan 請幫我做一個待辦清單網頁。
【目標】 給我自己每天用的簡單待辦清單,打開瀏覽器就能用。
【功能】
- 有一個輸入框和「新增」按鈕,輸入文字後按按鈕或按 Enter 就能新增一項。
- 每一項旁邊有「刪除」按鈕。
- 清單要自動儲存在瀏覽器的 localStorage,關掉網頁再打開,資料還在。
【限制】
- 全部寫在同一個 index.html 檔案裡,不使用任何外部套件或網路資源。
- 介面文字用繁體中文。
- 空白的內容不能被新增。
【怎樣算完成】 我用瀏覽器打開 index.html,可以新增三項、刪除一項,重新整理頁面後剩下的兩項還在。
請先提出計畫,有不確定的地方先問我。
審核計畫
Claude 會讀完你的需求,提出一份計畫,可能還會問你幾個問題(例如「要不要顯示新增的時間?」)。照你的想法回答就好,不確定就說「先不要,保持簡單」。
看計畫時,問自己三件事:
- 它要建立的檔案,是不是只有
index.html? - 我列的功能,它都有提到嗎?
- 有沒有多做我沒要求的東西?
都沒問題,就選核准,並手動核准每個修改。
第 2 步:讓 Claude 建立 index.html
核准後,Claude 會建立 index.html,並在寫入前讓你看內容。你的第一版大概會像這樣(每次產生的細節會不一樣,這很正常):
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>我的待辦清單</title>
<style>
body { font-family: sans-serif; max-width: 480px; margin: 40px auto; padding: 0 16px; }
form { display: flex; gap: 8px; }
#todo-input { flex: 1; padding: 8px; font-size: 16px; }
li { display: flex; justify-content: space-between; padding: 8px 0; }
</style>
</head>
<body>
<h1>我的待辦清單</h1>
<form id="todo-form">
<input id="todo-input" type="text" placeholder="要做什麼?">
<button type="submit">新增</button>
</form>
<ul id="todo-list"></ul>
<script>
const STORAGE_KEY = 'my-todos';
// 從瀏覽器讀出之前存的清單;沒有的話就從空清單開始
let todos = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
function save() {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
}
function render() {
const list = document.getElementById('todo-list');
list.innerHTML = '';
todos.forEach((todo) => {
const li = document.createElement('li');
const text = document.createElement('span');
text.textContent = todo.text;
const del = document.createElement('button');
del.textContent = '刪除';
del.addEventListener('click', () => {
todos = todos.filter((t) => t.id !== todo.id);
save();
render();
});
li.append(text, del);
list.appendChild(li);
});
}
document.getElementById('todo-form').addEventListener('submit', (event) => {
event.preventDefault(); // 不要讓表單重新整理頁面
const input = document.getElementById('todo-input');
const value = input.value.trim();
if (!value) return; // 空白的不新增
todos.push({ id: Date.now(), text: value });
input.value = '';
save();
render();
});
render();
</script>
</body>
</html>
不用逐行看懂。對照上面的四個零件,你大概能認出:style 裡是 CSS(外觀),body 裡的標籤是 HTML(骨架),script 裡是 JavaScript(動作),localStorage 那幾行是記憶。
請帶我導覽 index.html:把它分成四到五個區塊,每個區塊用一兩句白話說明它負責什麼。特別解釋 localStorage 是怎麼讓資料留下來的。
第 3 步:在瀏覽器打開,照清單試用
打開網頁的方法:
- 在檔案總管(Mac 是 Finder)找到
todo-app資料夾,雙擊index.html。 - 或請 Claude:「幫我用預設瀏覽器打開 index.html」(它會請你同意執行打開檔案的指令)。
- 用桌面 App 的話,Claude 也可以在內建的瀏覽器窗格裡打開預覽。
然後照著你寫的「怎樣算完成」親手測一次:
- 新增三項:「買牛奶」「繳電話費」「準備週會資料」。
- 試試看什麼都不打就按新增,應該不會出現空白項目。
- 刪除其中一項。
- 按 F5(Mac 是 Command + R)重新整理,剩下的兩項還在嗎?
第 4 步:沒問題,存檔
測試都通過了,就存一個存檔點:
測試都通過了。請幫我 commit,說明寫「待辦清單第一版:新增、刪除、自動儲存」。
第 2 輪:打勾完成、顯示剩幾件
有了存檔點,就可以放心改進了。這次功能比較小,可以直接用 Manual 模式,不一定要 Plan:
請幫待辦清單加上兩個功能:
- 每一項前面加一個勾選框。勾選後,文字變成灰色並加上刪除線;取消勾選就恢復。勾選狀態也要存進 localStorage。
- 清單下方顯示「還有 N 件事沒做」,N 是還沒勾選的數量。全部完成時改成顯示「全部完成,辛苦了!」
舊的資料沒有勾選狀態,請把它們當作未完成處理,不要讓舊資料壞掉。
注意最後一句。**「不要讓舊資料壞掉」**是很多新手會漏掉的需求:你第一輪存的資料沒有「完成」這個欄位,如果程式沒處理好,舊清單可能顯示錯誤。把它寫進需求,Claude 就會記得處理。
Claude 修改後,核心的新增部分大概像這樣:
// 勾選框:切換完成狀態
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = Boolean(todo.done); // 舊資料沒有 done,視為未完成
checkbox.addEventListener('change', () => {
todo.done = checkbox.checked;
save();
render();
});
if (todo.done) li.classList.add('done');
// 計算還剩幾件
const remaining = todos.filter((t) => !t.done).length;
document.getElementById('counter').textContent =
remaining === 0 ? '全部完成,辛苦了!' : `還有 ${remaining} 件事沒做`;
試用清單:打勾、取消打勾、重新整理後勾選狀態還在、計數正確、第一輪留下的舊項目正常顯示。都沒問題,請 Claude commit:「加上完成狀態與剩餘數量」。
第 3 輪:篩選,並讓手機也好用
最後一輪,加一個稍微複雜的功能。功能會動到好幾個地方,所以切回 Plan 模式:
/plan 請幫待辦清單再加兩個改進:
- 在清單上方加三個篩選按鈕:「全部」「未完成」「已完成」。目前選中的按鈕要看得出來。
- 讓版面在手機上也好用:按鈕和勾選框要大一點、好按,畫面窄的時候不要超出螢幕。
請特別確認:在「未完成」或「已完成」的篩選畫面裡刪除或打勾,動到的是正確的那一項。
那句「動到的是正確的那一項」不是多餘的。篩選後,畫面上的第 1 項不一定是清單裡的第 1 項,這是待辦清單最常見的錯誤之一。我們的第一版從一開始就幫每一項加了獨一無二的 id,所以通常不會出事,但要求 AI 檢查,再自己測一次,才是好習慣。
篩選的核心邏輯大概是:
let filter = 'all'; // 'all'、'active'、'done' 三種
const visible = todos.filter((t) => {
if (filter === 'active') return !t.done;
if (filter === 'done') return t.done;
return true;
});
試手機版面最簡單的方法:把瀏覽器視窗拉窄,或按 F12 打開開發者工具,切換成手機尺寸的預覽。
試用清單:三個篩選按鈕都正確;在篩選畫面裡打勾和刪除,動到的是對的項目;視窗拉窄後版面不會亂。通過之後,最後一次 commit:「加上篩選與手機版面」。
收尾:回顧你的作品
請 Claude 幫你回顧:
請用 git log 看看這個專案的存檔紀錄,幫我整理:這個待辦清單經歷了哪幾個版本、每個版本加了什麼。最後建議三個我下次可以自己試著加的功能,從簡單到難排列。
你會看到三、四個存檔點,每一個都是一個能用的版本。這就是用 AI 做東西最穩的節奏:小步前進,每一步都試用、都存檔。
- 跟著這堂課做完三輪,最後用
git log --oneline確認至少有四個存檔點(含「建立專案」)。 - 自己設計第 4 輪:從 Claude 建議的功能裡挑一個(例如「雙擊項目可以編輯文字」或「一鍵清除所有已完成」),用「目標、功能、限制、怎樣算完成」四段寫成需求說明書,交給 Claude 做。
- 第 4 輪做完、試用通過後先 commit。接著故意請 Claude 做一個你不滿意的改動,再用
git restore .(或/rewind選「只還原程式碼」)回到第 4 輪完成的樣子,確認你的安全網可靠。 - 把你的待辦清單網頁用一週,記下想改進的地方,下次再和 Claude 一起改。恭喜你,完成了這個單元!
讀完了嗎?
標記完成後,單元與專案的進度會自動更新(只存在這台裝置的瀏覽器)。
留言與討論
卡關了、有心得,或發現內容需要更新?都歡迎留言。留言使用 GitHub 帳號登入。