所有入門單元免費開放 · 課程內容持續更新中

行動練習:和 Claude 做一個待辦清單網頁

把整個單元串起來:從一個空資料夾開始,用需求說明書描述想要的網頁,在 Plan 模式下和 Claude 對齊計畫,讓它寫出一個會記住資料的待辦清單,再一輪一輪改進,每一輪都用 Git 存檔。

第 5.7 堂約 18 分鐘

這堂課要做什麼

這是本單元的最後一堂。前面六堂,你學會了:

  • 安裝和啟動 Claude Code(第 2 堂)
  • 在對的資料夾工作、寫 CLAUDE.md(第 3 堂)
  • 挑一個順手的介面(第 4 堂)
  • 用 Plan 和 Manual 模式安全地讓它動手(第 5 堂)
  • 用 Git 存檔,改壞了也能回來(第 6 堂)

今天要把這些全部用上,做出一個真的能用的待辦清單網頁:可以新增、打勾、刪除、篩選,而且關掉瀏覽器再打開,清單還在。

完成後的待辦清單網頁示意:有標題、輸入框和新增按鈕、全部未完成已完成三個篩選按鈕、三個待辦項目其中一個已打勾並劃線、每項都有刪除按鈕,下方顯示還有 2 件事沒做;右側標示四個零件:HTML 是骨架、CSS 是外觀、JavaScript 是動作、localStorage 是記憶

整個網頁只有一個檔案 index.html,裡面裝著這四個零件。

你不需要看懂所有程式碼。這堂課的重點是工作流程:怎麼描述、怎麼審核、怎麼試用、怎麼一輪一輪變好。

流程圖:0 準備資料夾、Git 和 CLAUDE.md,1 描述寫需求說明書,2 計畫用 Plan 模式並由你核准,3 建立由 Claude 寫 index.html,4 試用在瀏覽器打開照清單測試,5 commit 存一個存檔點,然後虛線回到描述進入下一輪;下方寫著三輪的內容

第 0 步:準備工作區

開一個新資料夾,不要和之前的學習筆記混在一起:

mkdir todo-app
cd todo-app
claude

用 VS Code 的話,選「檔案」→「開啟資料夾」打開 todo-app,再打開 Claude 面板。用桌面 App 的話,在 Code 分頁選這個資料夾。

確認現在是 Manual 模式(第 5 堂教過怎麼看),然後送出:

準備:Git 與 CLAUDE.md

這是一個新專案,我要做一個待辦清單網頁。請幫我:

  1. 執行 git init。
  2. 建立 CLAUDE.md,內容包含:
    • 專案說明:一個單一檔案的待辦清單網頁,用 HTML、CSS、JavaScript 寫成,不使用任何外部套件。
    • 與我合作的方式:一律用繁體中文;我是新手,解釋用白話;改檔案前先說明要改什麼。
  3. 做第一次 commit,說明寫「建立專案」。

逐一看過它要執行的指令,同意之後,你就有了一個乾淨的起點。

第 1 步:寫需求說明書

還記得「AI 寫程式入門」裡的需求說明書嗎?給 AI 的需求越清楚,第一版就越接近你要的。一份好的說明書包含四個部分:目標、功能、限制、怎樣算完成。

先切到 Plan 模式(Shift+Tab 或模式選單),再送出:

第 1 輪:需求說明書

/plan 請幫我做一個待辦清單網頁。

【目標】 給我自己每天用的簡單待辦清單,打開瀏覽器就能用。

【功能】

  1. 有一個輸入框和「新增」按鈕,輸入文字後按按鈕或按 Enter 就能新增一項。
  2. 每一項旁邊有「刪除」按鈕。
  3. 清單要自動儲存在瀏覽器的 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 那幾行是記憶。

想多懂一點?請 Claude 導覽

請帶我導覽 index.html:把它分成四到五個區塊,每個區塊用一兩句白話說明它負責什麼。特別解釋 localStorage 是怎麼讓資料留下來的。

第 3 步:在瀏覽器打開,照清單試用

打開網頁的方法:

  • 在檔案總管(Mac 是 Finder)找到 todo-app 資料夾,雙擊 index.html。
  • 或請 Claude:「幫我用預設瀏覽器打開 index.html」(它會請你同意執行打開檔案的指令)。
  • 用桌面 App 的話,Claude 也可以在內建的瀏覽器窗格裡打開預覽。

然後照著你寫的「怎樣算完成」親手測一次:

  1. 新增三項:「買牛奶」「繳電話費」「準備週會資料」。
  2. 試試看什麼都不打就按新增,應該不會出現空白項目。
  3. 刪除其中一項。
  4. 按 F5(Mac 是 Command + R)重新整理,剩下的兩項還在嗎?

第 4 步:沒問題,存檔

測試都通過了,就存一個存檔點:

第 1 輪存檔

測試都通過了。請幫我 commit,說明寫「待辦清單第一版:新增、刪除、自動儲存」。

第 2 輪:打勾完成、顯示剩幾件

有了存檔點,就可以放心改進了。這次功能比較小,可以直接用 Manual 模式,不一定要 Plan:

第 2 輪:完成狀態與計數

請幫待辦清單加上兩個功能:

  1. 每一項前面加一個勾選框。勾選後,文字變成灰色並加上刪除線;取消勾選就恢復。勾選狀態也要存進 localStorage。
  2. 清單下方顯示「還有 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 模式:

第 3 輪:篩選與版面

/plan 請幫待辦清單再加兩個改進:

  1. 在清單上方加三個篩選按鈕:「全部」「未完成」「已完成」。目前選中的按鈕要看得出來。
  2. 讓版面在手機上也好用:按鈕和勾選框要大一點、好按,畫面窄的時候不要超出螢幕。

請特別確認:在「未完成」或「已完成」的篩選畫面裡刪除或打勾,動到的是正確的那一項。

那句「動到的是正確的那一項」不是多餘的。篩選後,畫面上的第 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 做東西最穩的節奏:小步前進,每一步都試用、都存檔。

行動練習
  1. 跟著這堂課做完三輪,最後用 git log --oneline 確認至少有四個存檔點(含「建立專案」)。
  2. 自己設計第 4 輪:從 Claude 建議的功能裡挑一個(例如「雙擊項目可以編輯文字」或「一鍵清除所有已完成」),用「目標、功能、限制、怎樣算完成」四段寫成需求說明書,交給 Claude 做。
  3. 第 4 輪做完、試用通過後先 commit。接著故意請 Claude 做一個你不滿意的改動,再用 git restore .(或 /rewind 選「只還原程式碼」)回到第 4 輪完成的樣子,確認你的安全網可靠。
  4. 把你的待辦清單網頁用一週,記下想改進的地方,下次再和 Claude 一起改。恭喜你,完成了這個單元!

讀完了嗎?

標記完成後,單元與專案的進度會自動更新(只存在這台裝置的瀏覽器)。

卡住了?讓 AI 當你的家教複製這段提問範本,貼到 Claude 或其他 AI 工具,再補上你卡住的地方。

留言與討論

卡關了、有心得,或發現內容需要更新?都歡迎留言。留言使用 GitHub 帳號登入。

留言區即將開放。現在可以先到 GitHub 討論區 發問,或看看 交流頁 的其他管道。