學習Laravel13+Livewire3 - 文件 #4: 模組 3：Livewire 3 核心概念（8–10 小時）

Jeffery Hsu
2026-04-26T14:08:09Z

這進入 模組 3 的第二部分。這一次我們將專注於 表單處理 (Form Handling) 與 驗證 (Validation)，並實作一個完整的 Todo List。

在 Livewire 3 中，最推薦的處理方式是使用 Form Objects。這可以將表單的邏輯、驗證規則與主元件分離，讓程式碼更整潔且易於維護。

第一步：理解 Form Objects¶

Form Objects 是 Livewire 3 的新特性。當你的表單欄位很多時，不需要在主元件中寫一堆 public $title, public $content 等變數，而是封裝在一個專門的類別中。

1. 建立 TodoForm 物件
雖然沒有直接的 make:form 指令，但我們可以手動建立一個繼承自 Livewire\Form 的類別。
在 app/Livewire/ 下建立一個 Forms 資料夾，並新增 TodoForm.php：

namespace App\Livewire\Forms;

use Livewire\Attributes\Validate;
use Livewire\Form;
use App\Models\Todo; // 假設你已經按照模組 2 建立過這個 Model

class TodoForm extends Form
{
    // 使用 #[Validate] Attribute 定義驗證規則
    #[Validate('required|min:3', message: '待辦事項最少需要 3 個字')]
    public string $task = '';

    public function store()
    {
        // 執行驗證
        $this->validate();

        // 模擬存入資料庫 (或實作 Model)
        // Todo::create($this->all());

        // 重設欄位
        $this->reset();
    }
}

第二步：實作 Todo List 元件 (結合實時驗證)¶

現在我們建立主元件來使用這個 Form Object。

1. 建立 TodoList 元件

php artisan make:livewire TodoList

2. 撰寫 Class (app/Livewire/TodoList.php)

namespace App\Livewire;

use Livewire\Component;
use App\Livewire\Forms\TodoForm;

class TodoList extends Component
{
    // 注入 Form Object
    public TodoForm $form;

    // 模擬的待辦清單資料 (實務上會從資料庫抓)
    public array $todos = [
        ['id' => 1, 'task' => '學習 PHP 8.3 Attribute 新語法', 'completed' => true],
        ['id' => 2, 'task' => '設定 Laravel 13 開發環境', 'completed' => false],
    ];

    public function add()
    {
        // 呼叫 Form Object 的儲存邏輯
        $this->form->store();

        // 這裡僅作展示，實務上資料庫存完後會重新抓取 $this->todos
        session()->flash('status', '任務已成功新增！');
    }

    public function toggle($id)
    {
        // 模擬切換完成狀態
        foreach ($this->todos as &$todo) {
            if ($todo['id'] === $id) {
                $todo['completed'] = !$todo['completed'];
            }
        }
    }

    public function render()
    {
        return view('livewire.todo-list');
    }
}

第三步：撰寫 View (使用 Flux UI 與實時驗證)¶

打開 resources/views/livewire/todo-list.blade.php。
這裡我們會用到 wire:model.blur（離開輸入框時驗證）或 wire:model.live（邊打邊驗證）。


    <flux:heading size="xl" class="mb-6">我的待辦清單</flux:heading>

    @if (session('status'))

            {{ session('status') }}

    @endif



            <flux:input
                wire:model.blur="form.task"
                placeholder="輸入新任務..."
                class="flex-grow"
            />
            <flux:button type="submit" variant="primary">新增</flux:button>


        @error('form.task')
{{ $message }}
        @enderror



        @foreach($todos as $todo)


                    <flux:checkbox
                        wire:click="toggle({{ $todo['id'] }})"
                        :checked="$todo['completed']"
                    />

                        {{ $todo['task'] }}



                <flux:button
                    variant="ghost"
                    icon="trash"
                    size="sm"
                    class="opacity-0 group-hover:opacity-100 transition-opacity"
                />

        @endforeach



第四步：驗證作法¶

1. 將 <livewire:todo-list /> 加入你的儀表板頁面。

2. 驗證實時驗證 (Real-time Validation)：

在輸入框點擊一下，隨便打一個字，然後點擊頁面其他地方（觸發 blur 事件）。

你應該會立刻看到紅色的錯誤訊息：「待辦事項最少需要 3 個字」。這證明了驗證邏輯與 Form Object 運作成功。

3. 驗證資料提交：

輸入超過 3 個字的內容，按下 Enter 或點擊「新增」按鈕。

輸入框應該會自動清空（因為 form->reset()），且上方會出現綠色的成功提示。

4. 驗證交互：

點擊勾選方塊，確認任務文字是否會產生刪除線效果。

補充：依賴下拉選單 (Dependent Dropdowns) 小撇步¶

如果你需要實作「選擇縣市後自動載入行政區」，邏輯非常簡單：

1. 在 Class 定義 public $selectedCity = null。

2. 在 View 使用 wire:model.live="selectedCity"。

3. 在 Class 使用 Computed Property 根據 $this->selectedCity 回傳對應的行政區陣列。

4. 當 selectedCity 改變時，Livewire 會自動重新渲染行政區的 元件。

這就是模組 3 的第二部分。我們已經完成了 Form Objects、驗證、與 Todo List 實作。

準備好進入 第三部分 (事件系統、wire:navigate、檔案上傳與 Lazy Loading) 嗎？這一部分將讓你的 App 感覺更像是一個無縫的單頁應用 (SPA)！