Laravel Livewire 3å®å šã¬ã€ã 2026幎çïŒãªã¢ã¯ãã£ãã³ã³ããŒãã³ããšé¢æ¥å¯Ÿç
Laravel Livewire 3ã§ãªã¢ã¯ãã£ããªWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããæ¹æ³ã解説ãPHP 8屿§ãAlpine.jsçµ±åãã³ã³ããŒãã³ãèšèšãã¿ãŒã³ãæè¡é¢æ¥ã§åããããã€ã³ããŸã§ç¶²çŸ ã

Laravel Livewire 3ã¯ãPHPã ãã§ãªã¢ã¯ãã£ããªWebã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ã§ãããã¬ãŒã ã¯ãŒã¯ã§ããJavaScriptãã¬ãŒã ã¯ãŒã¯ãå¥éå°å ¥ããããšãªãããã€ãããã¯ãªãŠãŒã¶ãŒäœéšãå®çŸã§ããŸãã2026幎çŸåšãLivewire 3ã¯Alpine.jsãšã®æ·±ãçµ±åãããã©ãŒãã³ã¹ã®åäžãPHP 8屿§ã«ãã宣èšçãªæ§æãåããLaravelãšã³ã·ã¹ãã ã«ãããããã³ããšã³ãéçºã®äžæ žãšãªã£ãŠããŸãã
Livewire 3ã¯Alpine.jsãå
éšã§äœ¿çšããŠãããã¬ã€ã¢ãŠããã¡ã€ã«ã«@livewireStylesãš@livewireScriptsãã£ã¬ã¯ãã£ããå¿
èŠã§ããwire:modelãã£ã¬ã¯ãã£ãã¯ããã©ã«ãã§é
å»¶ãã€ã³ãã£ã³ã°ãšãªãããªã¢ã«ã¿ã€ã æŽæ°ã«ã¯wire:model.liveã䜿çšããŸãã
Livewire 3ã®ã¢ãŒããã¯ãã£ãšãªã¢ã¯ãã£ããã€ã³ãã£ã³ã°
Livewireã¯ããµãŒããŒäžã§åã¬ã³ããªã³ã°ãããPHPã³ã³ããŒãã³ããšããã©ãŠã¶ãžã®HTMLå·®åéä¿¡ãšããä»çµã¿ã§åäœããŸããåã³ã³ããŒãã³ãã¯ã·ãªã¢ã©ã€ãºæ©æ§ãéããŠãªã¯ãšã¹ãéã§ç¶æ ãä¿æããããããã£å€ãç¶æããŸãã
ãã®ã¢ãŒããã¯ãã£ã¯ãJavaScriptããŒã¹ã®ãªã¢ã¯ãã£ããã£ãšã¯æ ¹æ¬çã«ç°ãªããŸããã¯ã©ã€ã¢ã³ãåŽã§ä»®æ³DOMãç¶æãã代ããã«ãLivewireã¯ã³ã³ããŒãã³ãã®ç¶æ ãã·ãªã¢ã©ã€ãºããåãªã¯ãšã¹ããšå ±ã«éä¿¡ãããµãŒããŒããã®ã¬ã¹ãã³ã¹ã«åºã¥ããŠDOMãã¢ãŒãã£ã³ã°ããŸãããã®ã¢ãããŒãã«ãããããžãã¹ããžãã¯ãPHPã«ä¿ã¡ãªããããŠãŒã¶ãŒãæåŸ ãããªã¢ã¯ãã£ããªäœéšãæäŸã§ããŸãã
<?php
namespace App\Livewire;
use App\Models\User;
use Livewire\Component;
use Livewire\WithPagination;
use Livewire\Attributes\Url;
class SearchUsers extends Component
{
use WithPagination;
#[Url] // URLã¯ãšãªæååãšããããã£ãåæ
public string $search = '';
#[Url]
public string $role = '';
public function updatedSearch(): void
{
// æ€çޢ倿޿ã«ããŒãžããŒã·ã§ã³ããªã»ãã
$this->resetPage();
}
public function render()
{
return view('livewire.search-users', [
'users' => User::query()
->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%"))
->when($this->role, fn($q) => $q->where('role', $this->role))
->paginate(10),
]);
}
}#[Url]屿§ã¯ãããããã£ãURLã¯ãšãªãã©ã¡ãŒã¿ãšèªåçã«åæããã远å ã®ã³ãŒããªãã§å
±æå¯èœãªãã£ã«ã¿ãªã³ã°ãã¥ãŒãå®çŸããŸããupdatedSearchã©ã€ããµã€ã¯ã«ããã¯ã¯ãsearchããããã£ã倿Žããããšãã«ããªã¬ãŒãããããŒãžããŒã·ã§ã³ã1ããŒãžç®ã«ãªã»ããããŸãã
PHP 8屿§ã掻çšããLivewire 3ã³ã³ããŒãã³ãæ§æ
Livewire 3ã¯PHP 8屿§ãèšå®ã«æ¡çšãã以åã®ã¡ãœããããŒã¹ã®ã¢ãããŒãã眮ãæããŸããããã®å®£èšçãªã¹ã¿ã€ã«ã«ãããå¯èªæ§ãåäžããã³ã³ããŒãã³ãå šäœã®ãã€ã©ãŒãã¬ãŒããåæžãããŸãã
<?php
namespace App\Livewire;
use App\Models\Post;
use Livewire\Component;
use Livewire\Attributes\Rule;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Computed;
class CreatePost extends Component
{
#[Locked] // ããã³ããšã³ããã倿Žäžå¯
public int $userId;
#[Rule('required|min:5|max:200')]
public string $title = '';
#[Rule('required|min:50')]
public string $content = '';
#[Rule('nullable|array')]
public array $tags = [];
public function mount(): void
{
$this->userId = auth()->id();
}
#[Computed]
public function wordCount(): int
{
return str_word_count($this->content);
}
public function save(): void
{
$validated = $this->validate();
Post::create([
'user_id' => $this->userId,
...$validated,
]);
$this->reset(['title', 'content', 'tags']);
$this->dispatch('post-created');
}
public function render()
{
return view('livewire.create-post');
}
}#[Locked]屿§ã¯ãæ©å¯æ§ã®é«ãããããã£ã®ããã³ããšã³ãããã®æäœã鲿¢ããŸããIDãããŒããã·ã§ã³ãæž¡ãéã®ã»ãã¥ãªãã£ã«ãããŠéèŠã§ãã#[Rule]屿§ã¯ããªããŒã·ã§ã³ãã€ã³ã©ã€ã³ã§å®çŸ©ãã#[Computed]ã¯äŸåé¢ä¿ã倿ŽããããŸã§é«ã³ã¹ããªèšç®ããã£ãã·ã¥ããŸãã
ãŠãŒã¶ãŒIDãããŒããã·ã§ã³ãã©ã°ããã©ãŠã¶ããæ¹ãããããã¹ãã§ãªãããŒã¿ã«ã¯ãåžžã«#[Locked]ã䜿çšããŠãã ãããLivewireã¯åãªã¯ãšã¹ãã§ã³ã³ããŒãã³ãã®ç¶æ
ãéä¿¡ãããããä¿è·ãããŠããªãããããã£ã¯å€æŽã«å¯ŸããŠè匱ã§ãã
ãªã¢ã«ã¿ã€ã ãã©ãŒã ããªããŒã·ã§ã³ãšãŠãŒã¶ãŒãã£ãŒãããã¯
Livewireã¯ãããŒãžãªããŒããªãã§å³åº§ã«ããªããŒã·ã§ã³ãã£ãŒãããã¯ãæäŸããããšã«åªããŠããŸãããŠãŒã¶ãŒãå ¥åãããã³ã«ããããã£ãããªããŒã·ã§ã³ãããã©ãŒã ãã£ãŒã«ãã®æšªã«ãªã¢ã«ã¿ã€ã ã§ãšã©ãŒã衚瀺ããŸãã
<?php
namespace App\Livewire;
use App\Models\User;
use Livewire\Component;
use Livewire\Attributes\Rule;
use Livewire\Attributes\Validate;
use Illuminate\Validation\Rules\Password;
class RegistrationForm extends Component
{
#[Rule('required|email|unique:users,email')]
public string $email = '';
#[Rule('required|min:2|max:50')]
public string $name = '';
public string $password = '';
public string $passwordConfirmation = '';
public function rules(): array
{
return [
'password' => [
'required',
'confirmed',
Password::min(8)->mixedCase()->numbers(),
],
];
}
public function updated(string $property): void
{
// 倿޿ã«åäžããããã£ãããªããŒã·ã§ã³
$this->validateOnly($property);
}
public function register(): void
{
$validated = $this->validate();
$user = User::create([
'email' => $validated['email'],
'name' => $validated['name'],
'password' => bcrypt($validated['password']),
]);
auth()->login($user);
$this->redirect('/dashboard');
}
public function render()
{
return view('livewire.registration-form');
}
}察å¿ããBladeãã³ãã¬ãŒãã§ã¯ãwire:model.blurã䜿çšããŠãŠãŒã¶ãŒããã£ãŒã«ããé¢ãããšãã«ããªããŒã·ã§ã³ãããªã¬ãŒããã¬ã¹ãã³ã·ãæ§ãšãµãŒããŒè² è·ã®ãã©ã³ã¹ãåããŸãã
{{-- resources/views/livewire/registration-form.blade.php --}}
<form wire:submit="register" class="space-y-4">
<div>
<label for="email" class="block text-sm font-medium">ã¡ãŒã«ã¢ãã¬ã¹</label>
<input
wire:model.blur="email"
type="email"
id="email"
class="mt-1 block w-full rounded-md border-gray-300"
>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<div>
<label for="password" class="block text-sm font-medium">ãã¹ã¯ãŒã</label>
<input
wire:model.blur="password"
type="password"
id="password"
class="mt-1 block w-full rounded-md border-gray-300"
>
@error('password')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<div>
<label for="passwordConfirmation" class="block text-sm font-medium">ãã¹ã¯ãŒã確èª</label>
<input
wire:model.blur="passwordConfirmation"
type="password"
id="passwordConfirmation"
class="mt-1 block w-full rounded-md border-gray-300"
>
</div>
<button
type="submit"
class="w-full bg-indigo-600 text-white py-2 px-4 rounded-md"
wire:loading.attr="disabled"
>
<span wire:loading.remove>ç»é²ãã</span>
<span wire:loading>åŠçäž...</span>
</button>
</form>ãã®ãã¿ãŒã³ã¯Livewireã®åŒ·ã¿ã瀺ããŠããŸãããµãŒããŒãµã€ãã®ããªããŒã·ã§ã³ããžãã¯ãšã¯ã©ã€ã¢ã³ããµã€ãã®ã¬ã¹ãã³ã·ãæ§ãJavaScriptãªãã®ããŒãã£ã³ã°ç¶æ ãã³ã³ããŒãã³ãããžãã¯ãšãã¬ãŒã³ããŒã·ã§ã³ã®ã¯ãªãŒã³ãªåé¢ãå®çŸããŠããŸãã
ã€ãã³ãã䜿çšãã芪åã³ã³ããŒãã³ãééä¿¡
è€éãªã€ã³ã¿ãŒãã§ãŒã¹ã§ã¯ãè€æ°ã®Livewireã³ã³ããŒãã³ããçžäºã«éä¿¡ããå¿
èŠããããŸããLivewire 3ã¯ãdispatchãš#[On]屿§ãã¿ãŒã³ã䜿çšããæŽç·Žãããã€ãã³ãã·ã¹ãã ãæäŸããŸãã
<?php
namespace App\Livewire;
use App\Models\Task;
use Livewire\Component;
use Livewire\Attributes\On;
class TaskBoard extends Component
{
public array $columns = ['todo', 'in_progress', 'done'];
#[On('task-moved')]
public function handleTaskMoved(int $taskId, string $newStatus): void
{
Task::where('id', $taskId)->update(['status' => $newStatus]);
}
#[On('task-created')]
public function refreshBoard(): void
{
// ã³ã³ããŒãã³ãã¯èªåçã«åã¬ã³ããªã³ã°
}
public function render()
{
return view('livewire.task-board', [
'tasks' => Task::all()->groupBy('status'),
]);
}
}<?php
namespace App\Livewire;
use App\Models\Task;
use Livewire\Component;
class TaskCard extends Component
{
public Task $task;
public function moveToStatus(string $status): void
{
$this->dispatch('task-moved', taskId: $this->task->id, newStatus: $status);
}
public function render()
{
return view('livewire.task-card');
}
}ã€ãã³ãã¯ããã©ã«ãã§ã³ã³ããŒãã³ãéå±€ãããã«ã¢ããããŸãã芪åé¢ä¿å€ã®ã¯ãã¹ã³ã³ããŒãã³ãéä¿¡ã§ã¯ã$this->dispatch('event-name')->to(ComponentClass::class)ã䜿çšããŠç¹å®ã®ã³ã³ããŒãã³ããã¿ãŒã²ããã«ã§ããŸãã
Laravelã®é¢æ¥å¯Ÿçã¯ã§ããŠããŸããïŒ
ã€ã³ã¿ã©ã¯ãã£ããªã·ãã¥ã¬ãŒã¿ãŒãflashcardsãæè¡ãã¹ãã§ç·Žç¿ããŸãããã
ã¯ã©ã€ã¢ã³ããµã€ãã€ã³ã¿ã©ã¯ãã£ããã£ã®ããã®Alpine.jsçµ±å
Livewire 3ã«ã¯Alpine.jsããã³ãã«ãããŠãããåçŽãªã€ã³ã¿ã©ã¯ã·ã§ã³ã¯ã¯ã©ã€ã¢ã³ããµã€ãã§åŠçããè€éãªããžãã¯ã¯ãµãŒããŒã«ã©ãŠã³ãããªãããããã€ããªãããã¿ãŒã³ãå¯èœã§ãããã®çµã¿åããã«ãããåçŽãªUIãã°ã«ã®ãµãŒããŒè² è·ãåæžããªãããè€éãªããžãã¯ã«ã¯Livewireã®ãµãŒããŒãµã€ãã¢ãã«ãç¶æã§ããŸãã
{{-- resources/views/livewire/notification-dropdown.blade.php --}}
<div
x-data="{
open: false,
unreadCount: @entangle('unreadCount')
}"
class="relative"
>
<button @click="open = !open" class="relative p-2">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6 6 0 10-12 0v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
<span
x-show="unreadCount > 0"
x-text="unreadCount"
class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center"
></span>
</button>
<div
x-show="open"
@click.outside="open = false"
x-transition
class="absolute right-0 mt-2 w-80 bg-white rounded-lg shadow-lg"
>
@foreach($notifications as $notification)
<div
wire:click="markAsRead({{ $notification->id }})"
class="p-4 border-b hover:bg-gray-50 cursor-pointer"
>
<p class="font-medium">{{ $notification->title }}</p>
<p class="text-sm text-gray-600">{{ $notification->message }}</p>
</div>
@endforeach
</div>
</div>@entangleãã£ã¬ã¯ãã£ãã¯ãAlpine.jsã®ç¶æ
ãšLivewireããããã£ã®éã«åæ¹åãã€ã³ãã£ã³ã°ãäœæããŸããAlpineãŸãã¯Livewireã®ããããã§unreadCountã倿Žãããšãèªåçã«ããäžæ¹ã«åæããããµãŒããŒã®æš©åšãç¶æããªãããªããã£ãã¹ãã£ãã¯ãªUIæŽæ°ãå¯èœã«ãªããŸãã
ããã°ã¬ã¹ãã©ããã³ã°ä»ããã¡ã€ã«ã¢ããããŒã
Livewireã¯ãçµã¿èŸŒã¿ã®ããã°ã¬ã¹ãã©ããã³ã°ãããªããŒã·ã§ã³ãäžæã¹ãã¬ãŒãžãåãããã¡ã€ã«ã¢ããããŒãåŠçãæäŸããŸããWithFileUploadsãã¬ã€ãã¯ãä»»æã®ã³ã³ããŒãã³ãã«å¿
èŠãªãã¹ãŠã®æ©èœã远å ããŸãã
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Rule;
use Illuminate\Support\Facades\Storage;
class DocumentUploader extends Component
{
use WithFileUploads;
#[Rule('required|file|mimes:pdf,docx|max:10240')] // æå€§10MB
public $document;
public ?string $uploadedPath = null;
public function updatedDocument(): void
{
$this->validate();
}
public function save(): void
{
$this->validate();
$this->uploadedPath = $this->document->store('documents', 'public');
$this->dispatch('document-uploaded', path: $this->uploadedPath);
$this->reset('document');
}
public function render()
{
return view('livewire.document-uploader');
}
}{{-- resources/views/livewire/document-uploader.blade.php --}}
<div class="space-y-4">
<div
x-data="{ uploading: false, progress: 0 }"
x-on:livewire-upload-start="uploading = true"
x-on:livewire-upload-finish="uploading = false; progress = 0"
x-on:livewire-upload-error="uploading = false"
x-on:livewire-upload-progress="progress = $event.detail.progress"
>
<input
type="file"
wire:model="document"
accept=".pdf,.docx"
class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:bg-indigo-50 file:text-indigo-700"
>
<div x-show="uploading" class="mt-2">
<div class="bg-gray-200 rounded-full h-2">
<div
class="bg-indigo-600 h-2 rounded-full transition-all duration-300"
:style="'width: ' + progress + '%'"
></div>
</div>
<p class="text-sm text-gray-600 mt-1" x-text="'ã¢ããããŒãäž: ' + progress + '%'"></p>
</div>
</div>
@error('document')
<p class="text-sm text-red-600">{{ $message }}</p>
@enderror
@if($document)
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<span class="text-sm">{{ $document->getClientOriginalName() }}</span>
<button wire:click="save" class="bg-indigo-600 text-white px-4 py-2 rounded-md text-sm">
ã¢ããããŒã
</button>
</div>
@endif
</div>ãã®ãã³ãã¬ãŒãã¯ãã¯ã©ã€ã¢ã³ããµã€ãã®ããã°ã¬ã¹è¡šç€ºã«Alpine.jsããLivewireã®ã¢ããããŒãã€ãã³ããšçµã¿åãããŠããŸãããã¡ã€ã«ã¯æåã«äžæã¹ãã¬ãŒãžã«ã¢ããããŒããããæçµçãªã¹ãã¬ãŒãžã«ä¿åããåã«ãã¬ãã¥ãŒãšããªããŒã·ã§ã³ãå¯èœã«ãªããŸãã
Livewire 3éçºè åã颿¥è³ªåé
æè¡é¢æ¥ã§ã¯ãLivewireã®ã¢ãŒããã¯ãã£ãã»ãã¥ãªãã£ã¢ãã«ãããã©ãŒãã³ã¹ç¹æ§ã«ã€ããŠã®çè§£ãåãããããšãå€ãã§ãã以äžã®è³ªåã¯ãLivewireçµéšãæã€Laraveléçºè ãæ¡çšããéã«é »ç¹ã«ç»å ŽããŸãã
颿¥å®ã¯3ã€ã®äž»èŠãªé åãè©äŸ¡ããŸãïŒLivewireã®ãªã¯ãšã¹ãã©ã€ããµã€ã¯ã«ã®çè§£ããããªãã¯ããããã£ã«é¢ããã»ãã¥ãªãã£æèãã³ã³ããŒãã³ãããã©ãŒãã³ã¹ãæé©åããèœåã§ããLivewireã䜿ãã¹ãã§ãªãã±ãŒã¹ãç¥ãããšã¯ãäœ¿ãæ¹ãç¥ãããšãšåæ§ã«éèŠã§ãã
Livewireã¯ãªã¯ãšã¹ãéã§ã³ã³ããŒãã³ãã®ç¶æ ãã©ã®ããã«ç¶æããŸããïŒ
Livewireã¯ãåãªã¯ãšã¹ããšå ±ã«éä¿¡ããããã€ããŒãã«ãã¹ãŠã®ãããªãã¯ããããã£ãã·ãªã¢ã©ã€ãºããŸããã³ã³ããŒãã³ãã®ç¶æ ã¯ãšã³ã³ãŒããããæ¹ãããé²ãããã«çœ²åããããã©ãŠã¶ã«éä¿¡ãããŸãããã®åŸã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã§ããã®ãã€ããŒãã¯ãµãŒããŒã«æ»ããLivewireã¯ã¢ã¯ã·ã§ã³ãåŠçããåã«ã³ã³ããŒãã³ãã€ã³ã¹ã¿ã³ã¹ãåæ§ç¯ããŸãã
Livewireã®ãããªãã¯ããããã£ã«ã¯ã©ã®ãããªã»ãã¥ãªãã£äžã®æžå¿µããããLivewireã¯ãããã©ã®ããã«å¯ŸåŠããŠããŸããïŒ
ãããªãã¯ããããã£ã¯ããã©ãŠã¶ã«éä¿¡ãããã·ãªã¢ã©ã€ãºããããã€ããŒãã«å«ãŸããããè匱ã§ããæªæã®ãããŠãŒã¶ãŒã¯ããã®ãã€ããŒãããµãŒããŒã«éãè¿ãåã«å€æŽããå¯èœæ§ããããŸããLivewireã¯ãã§ãã¯ãµã æ€èšŒãéããŠããã«å¯ŸåŠããŠãããæ¹ããããããšãªã¯ãšã¹ãã倱æããŸããããã«ã#[Locked]屿§ã¯ããããã£ããµãŒããŒå°çšãšããŠããŒã¯ãããã§ãã¯ãµã ã䟵害ãããå Žåã§ãããã³ããšã³ããã倿Žãããããšãé²ããŸãã
wire:modelãwire:model.liveãwire:model.blurã®éãã説æããŠãã ããã
Livewire 3ã§ã¯ãwire:modelã¯ããã©ã«ãã§é
å»¶ãã€ã³ãã£ã³ã°ã䜿çšããŸããããããã£ã¯ããã©ãŒã éä¿¡ãªã©ã®ã¢ã¯ã·ã§ã³ãããªã¬ãŒããããšãã«ã®ã¿æŽæ°ãããŸããwire:model.liveã¯ãå
¥åã倿Žããããã³ã«ããããã£ãæŽæ°ããåããŒã¹ãããŒã¯ã§ãµãŒããŒã©ãŠã³ãããªãããããªã¬ãŒããŸããwire:model.blurã¯ãèŠçŽ ããã©ãŒã«ã¹ã倱ã£ããšãã«æŽæ°ããã¬ã¹ãã³ã·ãæ§ãšãµãŒããŒè² è·åæžã®ãã©ã³ã¹ãåããŸãã.debounce修食åã¯ã©ã€ãæŽæ°ã«é
å»¶ã远å ããŸãïŒwire:model.live.debounce.500msã
éçºè ã¯ã©ã®ãããªå Žåã«LivewireãããInertia.jsãJavaScriptãã¬ãŒã ã¯ãŒã¯ãéžæãã¹ãã§ããïŒ
Livewireã¯ãããŒã ãPHPã«åŒ·ãå°éç¥èãæã¡JavaScriptçµéšãéãããŠããå ŽåãSEOèŠä»¶ããµãŒããŒã¬ã³ããªã³ã°ã³ã³ãã³ããåªå ããå ŽåããŸãã¯è€éãªãµãŒããŒãµã€ãããªããŒã·ã§ã³ã䌎ããã©ãŒã ãæ±ãã¢ããªã±ãŒã·ã§ã³ã«æé©ã§ããInertia.jsãJavaScriptãã¬ãŒã ã¯ãŒã¯ã¯ãè€éãªã¯ã©ã€ã¢ã³ããµã€ãç¶æ ãæã€é«åºŠã«ã€ã³ã¿ã©ã¯ãã£ããªããã·ã¥ããŒãããªãã©ã€ã³æ©èœãå¿ èŠãšããã¢ããªã±ãŒã·ã§ã³ããŸãã¯SPAã®ã¡ã³ã¿ã«ã¢ãã«ã奜ãJavaScriptå°éç¥èãæã€ããŒã ã«ããé©ããŠããŸãã
Livewireã³ã³ããŒãã³ãã®ããã©ãŒãã³ã¹ãæé©åããã«ã¯ã©ãããã°ããã§ããïŒ
äž»èŠãªæé©åã«ã¯ä»¥äžãå«ãŸããŸãïŒãªã¯ãšã¹ããæžããããã«wire:model.liveã®ä»£ããã«wire:model.blurã䜿çšãããé«äŸ¡ãªèšç®ã«ãã£ãã·ã¥ãæå¹ã«ããããã«#[Computed]ãå®è£
ãããåæã¬ã³ããªã³ã°ããã©ãŒãã³ã¹ã®ããã«wire:initã§ã³ã³ããŒãã³ããé
å»¶ããŒãããããªã¯ãšã¹ãããšã«éä¿¡ãããããŒã¿ãå¶éããããã«ããŒãžããŒã·ã§ã³ã䜿çšããããªã¢ã¯ãã£ãããããã£ãã¹ã³ãŒãããŠäžå¿
èŠãªåã¬ã³ããªã³ã°ãé¿ããããªã¹ãã®å Žåãwire:key屿§ã¯ã¢ãŒãã£ã³ã°äžã«Livewireãã¢ã€ãã ãå¹ççã«è¿œè·¡ããã®ã«åœ¹ç«ã¡ãŸãã
Livewireãšäžç·ã«äœ¿çšãããLaravelã®ã€ãã³ãã·ã¹ãã ã®è©³çްã«ã€ããŠã¯ãã€ãã³ããšãªã¹ããŒã®é¢æ¥è³ªåãåç §ããŠãã ãããè€éãªLivewireã³ã³ããŒãã³ããæ§é åããéã«ã¯ãäŸåæ§æ³šå ¥ãã¿ãŒã³ã®çè§£ã䟡å€ããããŸãã
Livewireã³ã³ããŒãã³ãã®å¹æçãªãã¹ã
Livewireã¯ãLaravelã®ãã¹ããã¬ãŒã ã¯ãŒã¯ãšçµ±åãããã«ãšã³ããªãã¹ãAPIãæäŸããŸãããã¹ãã¯ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãã·ãã¥ã¬ãŒãããã³ã³ããŒãã³ãã®ç¶æ ãã¢ãµãŒãããDOMåºåãæ€èšŒã§ããŸãã
<?php
namespace Tests\Feature\Livewire;
use App\Livewire\SearchUsers;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;
class SearchUsersTest extends TestCase
{
use RefreshDatabase;
public function test_can_search_users_by_name(): void
{
User::factory()->create(['name' => 'John Doe', 'role' => 'admin']);
User::factory()->create(['name' => 'Jane Smith', 'role' => 'user']);
Livewire::test(SearchUsers::class)
->set('search', 'John')
->assertSee('John Doe')
->assertDontSee('Jane Smith');
}
public function test_can_filter_by_role(): void
{
User::factory()->create(['name' => 'Admin User', 'role' => 'admin']);
User::factory()->create(['name' => 'Regular User', 'role' => 'user']);
Livewire::test(SearchUsers::class)
->set('role', 'admin')
->assertSee('Admin User')
->assertDontSee('Regular User');
}
public function test_pagination_resets_on_search_change(): void
{
User::factory()->count(25)->create();
Livewire::test(SearchUsers::class)
->call('gotoPage', 2)
->assertSet('paginators.page', 2)
->set('search', 'test')
->assertSet('paginators.page', 1);
}
public function test_url_reflects_search_parameters(): void
{
Livewire::withQueryParams(['search' => 'existing'])
->test(SearchUsers::class)
->assertSet('search', 'existing');
}
}ãã®ãã¹ãã¹ã€ãŒãã¯ãæ©èœãç¶æ 管çãURLåæãã«ããŒããŠããŸããLivewireã³ã³ããŒãã³ããå«ãå æ¬çãªLaravelãã¹ãæŠç¥ã«ã€ããŠã¯ãLaravelãã¹ãã®ãã¹ããã©ã¯ãã£ã¹ã®èšäºã§è¿œå ã®ãã¿ãŒã³ãšãã¯ããã¯ãæäŸããŠããŸãã
ãŸãšã
- Livewire 3ã¯ããµãŒããŒãµã€ãã¬ã³ããªã³ã°ãšDOMã¢ãŒãã£ã³ã°ãéããŠãçŽç²ãªPHPã§ãªã¢ã¯ãã£ããªã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸããå€ãã®Laravelã¢ããªã±ãŒã·ã§ã³ã§å¥éJavaScriptãã¬ãŒã ã¯ãŒã¯ãå°å ¥ããå¿ èŠæ§ãæé€ããŸã
- PHP 8屿§ïŒ
#[Rule]ã#[Locked]ã#[Computed]ã#[Url]ïŒã¯ãã³ãŒãã®å¯èªæ§ãšã»ãã¥ãªãã£ãåäžããã宣èšçãªèšå®ãæäŸããŸã - ãã³ãã«ãããAlpine.jsçµ±åã«ãããåçŽãªã€ã³ã¿ã©ã¯ã·ã§ã³ã¯ã¯ã©ã€ã¢ã³ããµã€ãã«çãŸããè€éãªããžãã¯ã¯ãµãŒããŒäžã«æ®ããã€ããªãããã¿ãŒã³ãå¯èœã«ãªããŸã
- ã»ãã¥ãªãã£ã«ã¯æ³šæãå¿
èŠã§ãïŒæ©å¯æ§ã®é«ãããããã£ã«ã¯
#[Locked]ã䜿çšãããããªãã¯ããããã£ãåãªã¯ãšã¹ããã€ããŒãã§éä¿¡ãããããšãçè§£ããŠãã ãã - ããã©ãŒãã³ã¹æé©åã¯ãé©åãª
wire:model修食åãéããŠã©ãŠã³ãããªãããæžãããé«äŸ¡ãªæäœã«å¯ŸããŠã³ã³ãã¥ãŒãããããããã£ãå®è£ ããããšãäžå¿ãšããŠããŸã - 颿¥ã®è³ªåã¯ãã¢ãŒããã¯ãã£ã®çè§£ãã»ãã¥ãªãã£æèã代æ¿ã¢ãããŒãïŒInertia.jsãSPAïŒãããèŠä»¶ã«é©ããŠããå Žåãç¥ãããšã«çŠç¹ãåœãŠãŠããŸã
ä»ããç·Žç¿ãå§ããŸãããïŒ
颿¥ã·ãã¥ã¬ãŒã¿ãŒãšæè¡ãã¹ãã§ç¥èããã¹ãããŸãããã
å ±æ
é¢é£èšäº

Laravelãã¹ãå®å šã¬ã€ã2026ïŒPest 4ã»ã¢ãã¯ã»ã¢ãŒããã¯ãã£ãã¹ãã»æè¡é¢æ¥å¯Ÿç
Laravelã«ãããPest 4ãçšãããã¹ãææ³ã培åºè§£èª¬ããŠããããã¹ãããã£ãŒãã£ãŒãã¹ãããã¡ãµãŒãã®ã¢ãã¯ãã¢ãŒããã¯ãã£ãã¹ãããã¥ãŒããŒã·ã§ã³ãã¹ããæè¡é¢æ¥ã®é »åºè³ªåãŸã§ãç¶²çŸ çã«ç޹ä»ããŸãã

Laravel 12 æ°æ©èœãŸãšãïœã¹ã¿ãŒã¿ãŒãããå·æ°ã»WorkOS飿ºã»é¢æ¥å¯Ÿçã2026å¹Žææ°çã
Laravel 12ã®æ°æ©èœã培åºè§£èª¬ãBreeze/Jetstreamã«ä»£ããæ°ã¹ã¿ãŒã¿ãŒããããWorkOS AuthKitçµ±åãCarbon 3察å¿ãã¢ããã°ã¬ãŒãæé ã2026幎ç颿¥è³ªåãŸã§ç¶²çŸ çã«ç޹ä»ããŸãã

Laravel ãã¥ãŒãšãžã§ãïŒéåæã¢ãŒããã¯ãã£ãšé¢æ¥å¯Ÿç 2026
Laravelãã¥ãŒã·ã¹ãã ã®å éšåäœããžã§ãã®ãããåŠçã»ãã§ã€ãã³ã°ã»ãªãã©ã€æŠç¥ã解説ã2026å¹Žã®æè¡é¢æ¥ã§åããããã¥ãŒã¢ãŒããã¯ãã£ã®éèŠãã€ã³ããç¶²çŸ ããŸãã