2026'da Laravel Livewire 3: Reaktif Uygulamalar ve Mülakat Soruları

Laravel Livewire 3 ile reaktif bileşenler, PHP 8 nitelikleri, Alpine.js entegrasyonu ve teknik mülakatlara hazırlık konularını kapsayan kapsamlı rehber.

2026'da Laravel Livewire 3: Reaktif Uygulamalar ve Mülakat Soruları

Laravel Livewire 3, PHP geliştiricilerinin JavaScript yazmadan reaktif, dinamik arayüzler oluşturma biçimini dönüştürüyor. Framework'ün önemli bir evrimi olarak yayınlanan Livewire 3, Alpine.js entegrasyonu, morphing ile geliştirilmiş performans ve gerçek zamanlı uygulamaların Laravel ekosisteminde doğal hissettiren daha temiz bileşen sözdizimi sunuyor.

Livewire 3 Temel Değişiklik

Livewire 3, dahili olarak Alpine.js kullanır ve layout'ta @livewireStyles ve @livewireScripts direktiflerini gerektirir. wire:model direktifi artık varsayılan olarak lazy binding kullanır—gerçek zamanlı güncellemeler için wire:model.live kullanılmalıdır.

Livewire 3 Mimarisi ve Reaktif Bağlama

Livewire basit ama güçlü bir konsept üzerinden çalışır: sunucuda yeniden render edilen ve HTML farklarını tarayıcıya gönderen PHP bileşenleri. Her bileşen, özellik değerlerini koruyan bir serileştirme mekanizması aracılığıyla istekler arasında durumunu korur.

Mimari, JavaScript tabanlı reaktiviteden temelden farklıdır. İstemci tarafında sanal bir DOM tutmak yerine, Livewire bileşen durumunu serileştirir, her istekle birlikte gönderir ve sunucu yanıtına göre DOM'u morph eder. Bu yaklaşım, kullanıcıların beklediği reaktif deneyimi sunarken iş mantığını PHP'de tutar.

app/Livewire/SearchUsers.phpphp
<?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 query string ile özelliği senkronize eder
    public string $search = '';

    #[Url]
    public string $role = '';

    public function updatedSearch(): void
    {
        // Arama değiştiğinde sayfalamayı sıfırla
        $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] niteliği, özellikleri URL sorgu parametreleriyle otomatik olarak senkronize ederek ek kod olmadan paylaşılabilir filtrelenmiş görünümler sağlar. updatedSearch yaşam döngüsü hook'u, search özelliği değiştiğinde tetiklenir ve sayfalamayı birinci sayfaya sıfırlar.

PHP 8 Nitelikleri ile Livewire 3 Bileşen Sözdizimi

Livewire 3, yapılandırma için PHP 8 niteliklerini benimser ve önceki metot tabanlı yaklaşımı değiştirir. Bu deklaratif stil, okunabilirliği artırır ve bileşenler genelinde tekrarlayan kodu azaltır.

app/Livewire/CreatePost.phpphp
<?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] // Frontend'den değiştirilemez
    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] niteliği, hassas özelliklerin frontend'den manipüle edilmesini engeller—bu, ID'ler veya izinler geçirilirken güvenlik açısından kritiktir. #[Rule] nitelikleri inline doğrulama tanımlarken, #[Computed] bağımlılıklar değişene kadar pahalı hesaplamaları önbelleğe alır.

Güvenlik Değerlendirmesi

Kullanıcı ID'leri, izin bayrakları ve tarayıcıdan değiştirilmemesi gereken tüm veriler için her zaman #[Locked] kullanılmalıdır. Livewire, bileşen durumunu her istekte iletir ve korunmayan özellikleri manipülasyona açık hale getirir.

Gerçek Zamanlı Form Doğrulama ve Kullanıcı Geri Bildirimi

Livewire, sayfa yeniden yüklemeleri olmadan anında doğrulama geri bildirimi sağlamada üstündür. Framework, kullanıcılar yazarken özellikleri doğrular ve hataları form alanlarının yanında gerçek zamanlı olarak görüntüler.

app/Livewire/RegistrationForm.phpphp
<?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
    {
        // Değişiklikte tek özelliği doğrula
        $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');
    }
}

İlgili Blade şablonu, kullanıcılar bir alanı terk ettiğinde doğrulamayı tetiklemek için wire:model.blur kullanır ve yanıt verirlik ile sunucu yükü arasında denge kurar:

blade
{{-- 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">E-posta</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">Şifre</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">Şifreyi Onayla</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>Kayıt Ol</span>
        <span wire:loading>İşleniyor...</span>
    </button>
</form>

Bu kalıp Livewire'ın güçlü yanlarını gösterir: istemci tarafı yanıt verirliliği ile sunucu tarafı doğrulama mantığı, JavaScript olmadan yükleme durumları ve bileşen mantığı ile sunum arasında temiz ayrım.

Olaylarla Ebeveyn-Çocuk Bileşen İletişimi

Karmaşık arayüzler genellikle birbiriyle iletişim kuran birden fazla Livewire bileşeni gerektirir. Livewire 3, bu amaç için dispatch ve #[On] nitelik kalıbını kullanan geliştirilmiş bir olay sistemi sağlar.

app/Livewire/TaskBoard.php - Ebeveyn bileşenphp
<?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
    {
        // Bileşen otomatik olarak yeniden render edilir
    }

    public function render()
    {
        return view('livewire.task-board', [
            'tasks' => Task::all()->groupBy('status'),
        ]);
    }
}
app/Livewire/TaskCard.php - Çocuk bileşenphp
<?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');
    }
}

Olaylar varsayılan olarak bileşen hiyerarşisinde yukarı doğru kabarcıklanır. Ebeveyn-çocuk ilişkisi dışındaki bileşenler arası iletişim için olaylar, $this->dispatch('event-name')->to(ComponentClass::class) kullanılarak belirli bileşenleri hedefleyebilir.

Laravel mülakatlarında başarılı olmaya hazır mısın?

İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.

İstemci Tarafı Etkileşim için Alpine.js Entegrasyonu

Livewire 3, Alpine.js ile birlikte gelir ve bazı etkileşimlerin istemci tarafında gerçekleşirken diğerlerinin sunucuya gidiş-dönüş yaptığı hibrit kalıplara olanak tanır. Bu kombinasyon, karmaşık mantık için Livewire'ın sunucu tarafı modelini korurken basit UI geçişleri için sunucu yükünü azaltır.

blade
{{-- 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 direktifi, Alpine.js durumu ve Livewire özellikleri arasında çift yönlü bağlama oluşturur. unreadCount'taki değişiklikler Alpine veya Livewire'da otomatik olarak diğerine senkronize olur ve sunucu otoritesini korurken iyimser UI güncellemelerine olanak tanır.

İlerleme Takibi ile Dosya Yüklemeleri

Livewire, yerleşik ilerleme takibi, doğrulama ve geçici depolama ile dosya yükleme işleme sağlar. WithFileUploads trait'i, herhangi bir bileşene gerekli tüm işlevselliği ekler.

app/Livewire/DocumentUploader.phpphp
<?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')] // max 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');
    }
}
blade
{{-- 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="'Yükleniyor: ' + 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">
                Yükle
            </button>
        </div>
    @endif
</div>

Şablon, Livewire'ın yükleme olayları ile istemci tarafı ilerleme görselleştirmesi için Alpine.js'i birleştirir. Dosyalar önce geçici depolamaya yüklenir ve son depolamadan önce önizleme ve doğrulamaya olanak tanır.

Livewire 3 Geliştiricileri için Mülakat Soruları

Teknik mülakatlar genellikle Livewire'ın mimarisi, güvenlik modeli ve performans özelliklerinin anlaşılmasını araştırır. Aşağıdaki sorular, Livewire deneyimine sahip Laravel geliştiricileri işe alırken sıkça karşılaşılır.

Mülakat Odak Alanları

Mülakatçılar üç ana alanı değerlendirir: Livewire'ın istek yaşam döngüsünü anlama, public özelliklerle ilgili güvenlik farkındalığı ve bileşen performansını optimize etme yeteneği. Livewire'ı ne zaman KULLANMAMAK gerektiğini bilmek, nasıl kullanılacağını bilmek kadar önemlidir.

Livewire, istekler arasında bileşen durumunu nasıl korur?

Livewire, tüm public özellikleri her istekle birlikte seyahat eden bir payload'a serileştirir. Bileşenin durumu kodlanır, kurcalamayı önlemek için imzalanır ve tarayıcıya gönderilir. Sonraki etkileşimlerde bu payload sunucuya geri döner ve Livewire, eylemi işlemeden önce bileşen örneğini yeniden oluşturur.

Livewire public özelliklerinde hangi güvenlik endişeleri vardır ve Livewire bunları nasıl ele alır?

Public özellikler, tarayıcıya gönderilen serileştirilmiş payload'a dahil oldukları için savunmasızdır. Kötü niyetli kullanıcılar bu payload'u geri göndermeden önce değiştirebilir. Livewire bunu checksum doğrulaması ile ele alır—herhangi bir kurcalama isteğin başarısız olmasına neden olur. Ek olarak, #[Locked] niteliği özellikleri yalnızca sunucu tarafı olarak işaretler ve checksum'lar tehlikeye atılsa bile frontend'den değiştirilmelerini önler.

wire:model, wire:model.live ve wire:model.blur arasındaki farkı açıklayın.

Livewire 3'te wire:model varsayılan olarak ertelenmiş bağlama kullanır—özellik yalnızca bir eylem tetiklendiğinde güncellenir (form gönderimi gibi). wire:model.live, her input değişikliğinde özelliği günceller ve her tuş vuruşunda sunucu gidiş-dönüşü tetikler. wire:model.blur, element odağı kaybettiğinde güncellenir ve yanıt verirlik ile azaltılmış sunucu yükü arasında denge kurar. .debounce değiştiricisi live güncellemelere gecikme ekler: wire:model.live.debounce.500ms.

Bir geliştirici Inertia.js veya JavaScript framework yerine Livewire'ı ne zaman tercih etmelidir?

Livewire, ekibin güçlü PHP uzmanlığına sahip olduğu ancak sınırlı JavaScript deneyimi olduğu, SEO gereksinimlerinin sunucu tarafında render edilen içeriği tercih ettiği veya uygulamanın sunucu tarafı doğrulamalı karmaşık formlar içerdiği durumlarda en uygunudur. Inertia.js veya JavaScript framework'leri, karmaşık istemci tarafı durumuyla yüksek etkileşimli dashboard'lar, çevrimdışı işlevsellik gerektiren uygulamalar veya SPA mental modelini tercih eden JavaScript uzmanlığına sahip ekipler için daha uygundur.

Livewire bileşenleri performans için nasıl optimize edilir?

Anahtar optimizasyonlar şunlardır: istekleri azaltmak için wire:model.live yerine wire:model.blur kullanmak, önbelleğe almayı etkinleştirmek için pahalı hesaplamalar için #[Computed] uygulamak, ilk render performansı için wire:init ile bileşenleri lazy yüklemek, her istekte gönderilen veriyi sınırlamak için sayfalama kullanmak ve reaktif özellikleri kapsamlandırarak gereksiz yeniden render'ları önlemek. Listeler için wire:key niteliği, Livewire'ın morphing sırasında öğeleri verimli bir şekilde takip etmesine yardımcı olur.

Livewire ile birlikte kullanılan Laravel olay sistemini daha derinlemesine keşfetmek için olaylar ve dinleyiciler mülakat soruları makalesine bakılabilir. Dependency injection kalıplarını anlamak da karmaşık Livewire bileşenlerini yapılandırırken değerli olduğunu kanıtlar.

Livewire Bileşenlerini Etkili Test Etme

Livewire, Laravel'in test framework'ü ile entegre olan akıcı bir test API'si sağlar. Testler kullanıcı etkileşimlerini simüle edebilir, bileşen durumunu assert edebilir ve DOM çıktısını doğrulayabilir.

tests/Feature/Livewire/SearchUsersTest.phpphp
<?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');
    }
}

Test paketi işlevselliği, durum yönetimini ve URL senkronizasyonunu kapsar. Livewire bileşenleri dahil kapsamlı Laravel test stratejileri için Laravel test en iyi uygulamaları makalesi ek kalıplar ve teknikler sağlar.

Sonuç

  • Livewire 3, sunucu tarafı rendering ve DOM morphing aracılığıyla saf PHP'de reaktif arayüzlere olanak tanır ve birçok Laravel uygulamasında ayrı JavaScript framework'lerine olan ihtiyacı ortadan kaldırır
  • PHP 8 nitelikleri (#[Rule], #[Locked], #[Computed], #[Url]), kod okunabilirliğini ve güvenliğini artıran deklaratif yapılandırma sağlar
  • Dahili Alpine.js entegrasyonu, basit etkileşimlerin istemci tarafında kalırken karmaşık mantığın sunucuda kaldığı hibrit kalıplara olanak tanır
  • Güvenlik dikkat gerektirir: hassas özellikler için #[Locked] kullanılmalı ve public özelliklerin her istek payload'unda seyahat ettiği anlaşılmalıdır
  • Performans optimizasyonu, uygun wire:model değiştiricileri aracılığıyla gidiş-dönüşleri azaltmaya ve pahalı işlemler için computed özellikleri uygulamaya odaklanır
  • Mülakat soruları mimari anlayışına, güvenlik farkındalığına ve alternatif yaklaşımların (Inertia.js, SPA'lar) gereksinimlere ne zaman daha uygun olduğunu bilmeye odaklanır

Pratik yapmaya başla!

Mülakat simülatörleri ve teknik testlerle bilgini test et.

Paylaş

İlgili makaleler