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

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

這進入 模組 3 的第三部分（最終回）！這一部分包含的技術，會讓你的 Laravel 應用程式徹底擺脫傳統網頁的笨重感，擁有媲美 Vue/React 單頁應用 (SPA) 的流暢體驗，同時還能輕鬆處理檔案上傳與非同步載入。

我們將依序實作：SPA 導航、UX 狀態回饋、事件系統、檔案上傳，以及延遲載入 (Lazy Loading)。

第一步：SPA 體驗 (wire:navigate)¶

在過去，點擊連結換頁會讓整個瀏覽器畫面閃爍重新載入。Livewire 3 內建了強大的 wire:navigate，只需在 HTML 的 標籤加上一個屬性，就能讓頁面切換變成無縫的 SPA 體驗。

1. 實作與驗證
打開你的 resources/views/components/layouts/app.blade.php（或任何有導覽列的地方），修改你的連結：

文章列表

文章列表

儀表板

驗證：在瀏覽器點擊這些連結，你會發現網頁上方的進度條一閃而過，畫面瞬間切換，而且瀏覽器的重整圖示不會旋轉！

第二步：UX 增強 (wire:loading 與 wire:confirm)¶

在執行刪除或存檔等需要花點時間的動作時，給予使用者回饋是非常重要的。

1. 實作確認對話框與載入狀態
我們回到第二部分寫的 Todo List (resources/views/livewire/todo-list.blade.php)，修改刪除按鈕的部分：

<flux:button
    wire:click="delete({{ $todo['id'] }})"
    wire:confirm="你確定要刪除這個任務嗎？這個動作無法復原！"
    variant="danger"
    size="sm"
>
    刪除
</flux:button>


    正在刪除中...


第三步：事件系統與元件溝通 (Events)¶

如果頁面上有兩個不相關的 Livewire 元件（例如：一個「購物車按鈕」和一個「商品列表」），當商品列表點擊「加入」時，如何讓購物車按鈕的數字更新？這就是事件系統的工作。

1. 觸發事件 (Dispatch)
在任何一個元件的 PHP 方法中，你可以廣播一個事件：

public function addToCart()
{
    // ... 執行加入資料庫邏輯 ...

    // 觸發一個名為 'cart-updated' 的事件
    $this->dispatch('cart-updated');
}

2. 監聽事件 (Listen)
在另一個元件中（例如 CartIcon.php），使用 Laravel 13 支援的 PHP Attribute #[On] 來監聽：

namespace App\Livewire;

use Livewire\Component;
use Livewire\Attributes\On;

class CartIcon extends Component
{
    public int $count = 0;

    // 當接收到 'cart-updated' 事件時，執行此方法
    #[On('cart-updated')]
    public function updateCount()
    {
        $this->count++; // 或從資料庫重新抓取最新數量
    }

    public function render()
    {
        return view('livewire.cart-icon');
    }
}

第四步：檔案上傳與即時預覽 (File Uploads)¶

Livewire 把檔案上傳變得不可思議的簡單，甚至內建了暫存與預覽機制。

1. 建立上傳元件

php artisan make:livewire ProfileUploader

2. 撰寫 Class (必須引入 WithFileUploads Trait)
打開 app/Livewire/ProfileUploader.php：

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Validate;

class ProfileUploader extends Component
{
    use WithFileUploads; // 必須加入這個 Trait 才能處理檔案

    // 加上驗證規則：必須是圖片，最大 2MB
    #[Validate('image|max:2048')]
    public $photo;

    public function save()
    {
        $this->validate();

        // 將檔案儲存到 storage/app/public/photos 目錄下
        $path = $this->photo->store('photos', 'public');

        session()->flash('message', '大頭貼上傳成功！路徑：' . $path);
    }

    public function render()
    {
        return view('livewire.profile-uploader');
    }
}

3. 撰寫 View (包含即時預覽)
打開 resources/views/livewire/profile-uploader.blade.php：


    <flux:heading size="lg" class="mb-4">更新大頭貼</flux:heading>




@error('photo') {{ $message }} @enderror

        @if ($photo)

圖片預覽：
temporaryUrl() }}" class="w-32 h-32 object-cover rounded-full border">

        @endif


            <flux:button type="submit" variant="primary">儲存圖片</flux:button>
正在上傳至暫存區...



    @if (session('message'))
{{ session('message') }}
    @endif


驗證：將 <livewire:profile-uploader /> 放進頁面測試。選取圖片後，你會看到旁邊出現「正在上傳」，接著立刻顯示圖片預覽（此時還沒正式存進資料庫），最後按下儲存才完成。

第五步：效能優化 (Lazy Loading 與 Polling)¶

1. Lazy Loading (延遲載入)
如果某個元件需要查詢超大資料庫，會拖慢整個頁面的初始載入時間。你可以加上 #[Lazy]。

use Livewire\Attributes\Lazy;

#[Lazy] // 加上這個，該元件就不會跟隨主頁面一起載入
class HeavyChart extends Component
{
    public function render()
    {
        // 模擬耗時 2 秒的複雜查詢
        sleep(2);
        return view('livewire.heavy-chart');
    }

    // 在資料載入前，前端會顯示這個 Placeholder
    public function placeholder()
    {
        return <<<'HTML'

                載入複雜圖表中，請稍候...

        HTML;
    }
}

2. Polling (定期輪詢)
如果你需要實作「即時股價看板」或「系統監控」，只需在 HTML 加上 wire:poll：


    目前伺服器 CPU 使用率：{{ $cpuUsage }} %


恭喜！到這裡為止，你已經完全掌握了 Livewire 3 的全貌，並且具備了開發高度互動式應用的能力。

前三個模組（環境架構、資料庫與 ORM、Livewire 反應式前端）是整個 Laravel 13 開發的最核心基石。接下來，我們將邁入 模組 4：進階與 API 開發（包含身分驗證、Sanctum API、Job 佇列與排程）。

你希望我們先複習一下前三個模組的內容，還是直接著手進行模組 4 呢？