Laravel Blade Components Slots View Composers View Models
Blade memberi beberapa cara untuk merapikan layer view. Empat pola yang paling sering muncul adalah Blade components, slots, view composers, dan view models. Keempatnya sama-sama membantu menjaga template tetap sehat, tapi perannya berbeda.
Kalau dipakai dengan tepat, kita bisa memisahkan:
- struktur UI reusable ke component
- konten variabel ke slot
- data view-level yang perlu otomatis tersedia ke view composer
- transformasi data khusus presentasi ke view model
Kalau dipakai sembarangan, view justru pelan-pelan berubah jadi tempat campur aduk antara markup, query, formatting, dan keputusan bisnis kecil.
Definisi singkat
Blade component
Blade component adalah potongan view yang bisa dipakai ulang sebagai tag atau include terstruktur. Tujuannya bukan cuma menghindari duplikasi HTML, tapi juga membuat batas tanggung jawab UI lebih jelas.
Contoh bentuk umum:
<x-alert type="success">
Berhasil menyimpan data.
</x-alert>Slot
Slot adalah tempat isi dinamis yang dimasukkan ke dalam component dari luar. Slot membuat component tetap reusable tanpa memaksa semua isi ditulis lewat atribut.
View composer
View composer adalah callback atau class yang menyiapkan data untuk view tertentu sebelum view dirender. Ini berguna kalau beberapa view selalu butuh data yang sama dan data itu lebih cocok disiapkan dari luar template.
View model
View model adalah objek yang khusus menyiapkan data untuk view. Ia biasanya mengambil data domain lalu mengubahnya menjadi bentuk yang enak dipakai template: string yang sudah diformat, boolean untuk state UI, daftar item yang sudah dirapikan, atau label yang sudah dipetakan.
Kapan Blade component dipakai
Pakai Blade component kalau kamu ingin menyatukan struktur markup yang berulang.
Cocok untuk:
- button
- card
- modal
- form input group
- alert / notification
- badge / pill
- layout section yang berulang
Blade component membantu saat:
- markup berulang di banyak halaman
- struktur HTML punya variasi kecil tapi pola dasarnya sama
- UI perlu konsisten
- ada state visual yang sebaiknya dinyatakan sebagai props, bukan copy-paste HTML
Jangan pakai component kalau:
- cuma ada satu potong HTML kecil yang tidak akan dipakai ulang
- isi component terlalu banyak keputusan bisnis
- component mulai memuat query, auth check, atau branching yang seharusnya ada di layer lain
Aturan praktis
Kalau yang kamu ulang adalah bentuk UI, pakai component. Kalau yang kamu ulang adalah logika data, pikirkan view model atau composer.
Cara kerja Blade component
Blade component menerima:
- props: data input dari pemanggil
- slot: isi blok utama yang ditempelkan dari luar
- named slots: area tertentu yang bisa diisi terpisah
Urutannya sederhana:
- view utama dirender
- Blade menemukan tag component
- props diteruskan ke component
- isi slot dimasukkan ke placeholder component
- hasil akhir jadi HTML yang dirender ke browser
Bagaimana slot bekerja
Slot adalah mekanisme untuk menyisipkan isi ke dalam component.
Default slot
Default slot adalah konten di antara tag pembuka dan penutup component.
<x-card>
<p>Isi kartu ini.</p>
</x-card>Di dalam component, isi itu biasanya ditampilkan dengan:
<div class="card">
{{ $slot }}
</div>Named slot
Named slot dipakai kalau component punya lebih dari satu area isi.
<x-modal>
<x-slot:title>
Hapus data
</x-slot:title>
<p>Data ini tidak bisa dikembalikan.</p>
</x-modal>Di component:
<div class="modal">
<h2>{{ $title }}</h2>
<div>{{ $slot }}</div>
</div>Kapan slot lebih tepat daripada prop
Slot lebih pas kalau isinya:
- markup kompleks
- bisa berisi HTML nested
- perlu fleksibel tanpa menambah banyak prop
- bukan sekadar string pendek
Kalau isinya hanya nilai sederhana seperti label, class, atau status, prop biasanya lebih bersih.
Jebakan slot
- component jadi terlalu “bentuk kosong” tanpa konteks
- banyak slot membuat pemakaian component susah dibaca
- isi slot diam-diam mengandung logic yang mestinya pindah ke view model atau controller
Kapan view composer membantu
View composer membantu kalau ada data yang:
- dibutuhkan oleh banyak view
- selalu sama pola persiapannya
- tidak enak diulang di setiap controller
- bukan bagian dari domain utama halaman, tapi tetap dibutuhkan untuk render
Contoh umum:
- navigation menu
- user profile summary di sidebar
- daftar kategori di layout
- notification count
- settings atau flags global untuk UI
Kapan composer tepat
Pakai composer kalau:
- data dipakai lintas banyak halaman
- data hanya perlu ada saat view dirender
- view perlu data yang sama tanpa mengotori controller
- kamu ingin mengurangi boilerplate di action yang berbeda-beda
Kapan composer tidak tepat
Jangan jadikan composer tempat semua hal.
Hindari composer kalau:
- data itu cuma dipakai satu view
- data berasal dari proses bisnis yang jelas dan sebaiknya tetap di controller/service
- composer mulai menjalankan query berat untuk setiap request tanpa kontrol
- data jadi sulit dilacak karena “muncul sendiri” di view
Prinsip aman
View composer bagus untuk data pelengkap presentasi, bukan untuk memindahkan semua logic dari controller.
Kapan view models dipakai
View model cocok kalau template butuh data yang sudah dibentuk khusus untuk presentasi.
Contoh kasus:
- nama tampil yang harus fallback ke email
- harga yang perlu diformat
- status label yang memetakan enum ke teks warna
- daftar action yang tergantung state objek
- data gabungan dari beberapa sumber yang hanya dipakai di UI
View model membantu ketika
- controller mulai penuh dengan formatting
- view dipenuhi logika kecil seperti
@if,@switch, ternary yang berulang - representasi data untuk UI berbeda dari model domain mentah
- kamu ingin unit test untuk aturan presentasi
Perbedaan sederhana
- Controller: mengatur request dan alur utama
- View composer: menyuplai data pelengkap ke view tertentu
- View model: membentuk data presentasi
- Blade component: menyusun UI reusable
Alur render
Diagram di atas menunjukkan urutan besar yang biasanya terjadi. Composer bekerja di tahap render view, sedangkan component dan slot menyusun markup final.
Struktur penggunaan yang sehat
Pola yang sehat biasanya seperti ini:
- Controller menyiapkan data utama halaman
- View model merapikan data untuk presentasi
- View composer menambahkan data yang umum dipakai oleh view tertentu
- Blade component mengurusi ulang struktur UI
- Slot menyisipkan isi yang fleksibel
Contoh pembagian kerja:
- controller mengirim
Invoice - view model mengubah invoice menjadi
total_formatted,status_label, dancan_pay - composer menambahkan
sidebarLinks - component
<x-invoice-summary>merender blok ringkasan - slot mengisi catatan khusus atau CTA
Contoh ringkas
Component
{{-- resources/views/components/button.blade.php --}}
<button {{ $attributes->merge(['class' => 'btn']) }}>
{{ $slot }}
</button>Pemakaian:
<x-button class="btn-primary">
Simpan
</x-button>Named slot
<x-panel>
<x-slot:header>
Detail pengguna
</x-slot:header>
<p>Nama: {{ $user->name }}</p>
</x-panel>View composer
use Illuminate\Support\Facades\View;
View::composer('layouts.app', function ($view) {
$view->with('navLinks', [
['label' => 'Dashboard', 'url' => route('dashboard')],
['label' => 'Profile', 'url' => route('profile')],
]);
});View model
final class UserProfileViewModel
{
public function __construct(private readonly User $user) {}
public function name(): string
{
return $this->user->name ?: $this->user->email;
}
public function statusLabel(): string
{
return $this->user->is_active ? 'Aktif' : 'Nonaktif';
}
}Jebakan umum saat view logic membesar
Ini bagian yang paling sering bikin view Laravel pelan-pelan berantakan.
1. Logic bisnis ikut masuk ke Blade
Kalau Blade mulai berisi perhitungan status, filtering data, atau branching kompleks, view sudah terlalu berat.
Tanda-tandanya:
@ifbertumpuk- helper dipanggil berkali-kali di template
- view mengandung perbandingan yang seharusnya punya nama jelas
2. Component jadi mini-controller
Component seharusnya fokus pada UI. Kalau component mulai query database, akses service yang kompleks, atau memutuskan business rule utama, batas tanggung jawabnya sudah kabur.
3. Composer jadi tempat magic
View composer yang terlalu pintar bikin dependency sulit dilacak. View tampak “bersih”, tapi data datang dari tempat yang tidak langsung terlihat.
4. Data presentasi tidak dibedakan dari domain data
Template biasanya butuh data yang sudah dipermudah. Kalau semua data domain dilempar mentah ke view, template akan menanggung terlalu banyak tanggung jawab.
5. Duplikasi formatting
Format tanggal, mata uang, status label, dan fallback text yang diulang di banyak view adalah sinyal kuat untuk pindah ke view model atau helper yang lebih jelas.
Panduan memilih pola
Pilih begini:
- Komponen UI berulang → Blade component
- Isi fleksibel di dalam component → Slot
- Data bersama untuk view tertentu → View composer
- Transformasi data untuk presentasi → View model
Kalau satu halaman punya semua masalah sekaligus, jangan dipaksa diselesaikan dengan satu pola saja. Pisahkan sesuai tugasnya.
Kesalahan implementasi yang sering muncul
- memakai component untuk semua hal, termasuk data shaping
- memakai composer untuk menutup masalah arsitektur controller yang terlalu gemuk
- menaruh query berat di composer yang dieksekusi di banyak view
- membiarkan slot berisi logic yang sulit dibaca
- tidak memberi nama jelas untuk data presentasi
Ringkasan cepat
- Blade component: dipakai untuk markup/UI yang reusable.
- Slot: dipakai untuk menyisipkan isi fleksibel ke dalam component.
- View composer: dipakai untuk data pelengkap yang perlu tersedia otomatis saat view dirender.
- View model: dipakai untuk membentuk data presentasi agar view tetap tipis.
Kalau tujuan utamanya menjaga maintainability, aturan paling aman adalah: view hanya merakit tampilan, bukan menyelesaikan semua logic.
Referensi terkait
- Laravel Blade Components
- Laravel View Composers
- Laravel View Models pattern
- Laravel service container dan dependency injection
- Eloquent relationship dan query pattern