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 集成。