Chuyển đến nội dung chính

第 17 課:Livewire — 全端組件

Livewire 3,電線:模型,電線:點選。組件生命週期、反應性屬性。文件上傳、分頁。延遲載入、輪詢。 Alpine.js 整合。 SPA般的體驗。

💻 程式設計 — 第 17 課 第 17 課:Livewire — 全端組件

Laravel:從基礎到高級

第 5 部分:現代全端

亞洲開發網

1.Livewire 3 設定

composer require livewire/livewire
php artisan make:livewire ProductSearch

2.Livewire組件

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use Livewire\Attributes\Url;

class ProductSearch extends Component
{
    use WithPagination;

    #[Url]
    public string $search = '';
    public string $category = '';
    public string $sortBy = 'created_at';

    public function updatedSearch()
    {
        $this->resetPage();
    }

    public function render()
    {
        $products = Product::query()
            ->when($this->search, fn ($q) => $q->where('name', 'like', "%{$this->search}%"))
            ->when($this->category, fn ($q) => $q->where('category_id', $this->category))
            ->orderByDesc($this->sortBy)
            ->paginate(20);

        return view('livewire.product-search', compact('products'));
    }
}
{{-- resources/views/livewire/product-search.blade.php --}}
<div>
    <input wire:model.live.debounce.300ms="search" placeholder="Tìm kiếm..." />

    <select wire:model.live="category">
        <option value="">Tất cả</option>
        @foreach($categories as $cat)
            <option value="{{ $cat->id }}">{{ $cat->name }}</option>
        @endforeach
    </select>

    @foreach($products as $product)
        <x-product-card :product="$product" />
    @endforeach

    {{ $products->links() }}
</div>

3. 行動與事件

class Cart extends Component
{
    public array $items = [];

    public function addToCart(int $productId)
    {
        $product = Product::findOrFail($productId);
        $this->items[] = $product->toArray();
        $this->dispatch('cart-updated', count: count($this->items));
    }

    public function removeItem(int $index)
    {
        unset($this->items[$index]);
        $this->items = array_values($this->items);
    }
}

4. 文件上傳

use Livewire\WithFileUploads;

class AvatarUpload extends Component
{
    use WithFileUploads;

    public $photo;

    public function save()
    {
        $this->validate(['photo' => 'image|max:2048']);
        $path = $this->photo->store('avatars', 'public');
        auth()->user()->update(['avatar' => $path]);
    }
}

5.Alpine.js 集成

<div x-data="{ open: false }">
    <button @click="open = !open">Toggle</button>
    <div x-show="open" x-transition>
        <livewire:product-details :product="$product" />
    </div>
</div>

下一篇: Inertia.js 和 Vue/React 集成。