เริ่มต้นด้วยคำถามที่น่าคิด
ถ้าถามนักพัฒนา Laravel หลายคนว่า "ใช้ Blade ฟีเจอร์อะไรบ้าง?" คำตอบที่ได้มักจะวนเวียนอยู่กับ @if, @foreach, @extends, @yield, @include แล้วก็จบ
ซึ่งก็ไม่ผิดอะไร — ฟีเจอร์พวกนี้ใช้ได้จริง ทำงานได้จริง
แต่ถ้าคุณยังเขียน HTML ซ้ำไปซ้ำมาทุกหน้า หรือต้อง copy <div class="card">...</div> ไปวางทุกครั้งที่ต้องการ Card — แสดงว่าคุณยังไม่ได้แตะ Blade Component เลย
บทความนี้จะพาคุณรู้จักกับ Blade Component แบบที่ใช้งานได้จริง พร้อมตัวอย่างโค้ดครบถ้วน
Blade Component คืออะไร?
Blade Component คือการแยกชิ้นส่วน UI ออกมาเป็นไฟล์ของตัวเอง แล้วเรียกใช้ซ้ำได้ทุกที่ในโปรเจกต์
ลองนึกภาพว่าคุณมี UI element ที่ใช้บ่อย เช่น Card, Alert, Button, Form Input หรือ Modal — แทนที่จะ copy HTML ไปวางทุกหน้า คุณสร้างมันครั้งเดียว แล้วเรียกใช้แบบนี้:
<x-card title="สรุปยอดขาย">
เนื้อหาอยู่ตรงนี้
</x-card>แก้ที่เดียว มีผลทุกหน้า — ไม่ต้องตามแก้ทีละจุดอีกต่อไป
5 Blade Component Features ที่ช่วยประหยัดเวลา 10+ ชั่วโมง
มาดูกันทีละฟีเจอร์ พร้อมตัวอย่างโค้ดที่ใช้งานได้จริง
1Anonymous Components — เริ่มต้นง่าย ไม่ต้องมี Class
Anonymous Component คือ Component ที่ไม่ต้องสร้าง PHP Class ประกอบ วางไฟล์ Blade ไว้ใน resources/views/components/ แล้วเรียกใช้ได้เลย
<div class="alert alert-{{ $type ?? 'info' }}">
{{ $slot }}
</div><x-alert type="success">
บันทึกข้อมูลสำเร็จแล้ว!
</x-alert>💡
ไม่ต้องรัน artisan ไม่ต้องสร้าง Class เพิ่ม เหมาะมากสำหรับ Component เล็ก ๆ ที่แค่รับค่ามาแสดงผล
2Class-based Components — เมื่อต้องการ Logic เพิ่มเติม
เมื่อ Component ต้องการ logic เช่น ดึงข้อมูลจาก DB หรือมีการคำนวณ ให้ใช้ Class-based Component
php artisan make:component UserCard
class UserCard extends Component
{
public string $name;
public string $role;
public function __construct(string $name, string $role = 'Member')
{
$this->name = $name;
$this->role = $role;
}
public function render()
{
return view('components.user-card');
}
}<div class="user-card">
<h3>{{ $name }}</h3>
<span class="badge">{{ $role }}</span>
</div><x-user-card name="สมชาย" role="Admin" />
3Props — รับค่าเข้า Component แบบมีระเบียบ
Props คือวิธีส่งค่าเข้า Component ใน Anonymous Component ใช้ @props เพื่อประกาศว่า Component รับค่าอะไรบ้าง และกำหนดค่า default ได้เลย
@props([
'type' => 'text',
'label' => '',
'name',
'value' => '',
])
<div class="form-group">
<label>{{ $label }}</label>
<input
type="{{ $type }}"
name="{{ $name }}"
value="{{ $value }}"
class="form-control"
>
</div><x-form.input label="อีเมล" name="email" type="email" :value="old('email')" />💡
:value="old('email')" มี : นำหน้า หมายความว่าค่าที่ส่งเป็น PHP expression ไม่ใช่ string ธรรมดา
4Slots — พื้นที่สำหรับใส่เนื้อหาอิสระ
Slot คือช่องว่างภายใน Component ที่ให้ผู้เรียกใช้กำหนดเนื้อหาเองได้
<div class="card">
@if (isset($header))
<div class="card-header">{{ $header }}</div>
@endif
<div class="card-body">{{ $slot }}</div>
@if (isset($footer))
<div class="card-footer">{{ $footer }}</div>
@endif
</div><x-card>
<x-slot:header>
สรุปยอดขายประจำเดือน
</x-slot:header>
<p>ยอดรวม: 125,000 บาท</p>
<x-slot:footer>
อัปเดตล่าสุด: {{ now()->format('d/m/Y') }}
</x-slot:footer>
</x-card>5Attribute Bag / Merge Class — จัดการ HTML Attribute อย่างฉลาด
นี่คือฟีเจอร์ที่หลายคนลืมว่ามีอยู่ แต่มีประโยชน์มาก เมื่อคุณส่ง HTML attribute เพิ่มเข้าไปใน Component ทุกอย่างจะถูกเก็บไว้ใน $attributes object อัตโนมัติ
@props(['type' => 'text', 'name'])
<input
type="{{ $type }}"
name="{{ $name }}"
{{ $attributes->merge(['class' => 'form-control']) }}
>
{{-- เรียกใช้ --}}
<x-form.input name="phone" class="w-full" placeholder="กรอกเบอร์โทร" />
{{-- ผลลัพธ์ที่ได้ --}}
<input type="text" name="phone" class="form-control w-full" placeholder="กรอกเบอร์โทร">Real-world Example: Building a Form Component
ก่อนที่ Laravel จะมีรูปแบบ <x-component> นักพัฒนาหลายคนคุ้นเคยกับ @component แบบนี้:
@component('components.card', ['title' => 'Hello'])
เนื้อหาภายใน Card
@endcomponentปัจจุบัน Laravel นิยมใช้รูปแบบ <x-component-name> มากกว่า เพราะ:
- อ่านได้ง่ายกว่า เหมือน HTML tag ปกติ
- จัดการ props ได้สะดวกและตรงไปตรงมากว่า
- รองรับ Named Slot ได้ดีกว่า
- เป็นมาตรฐานใหม่ของ Laravel ตั้งแต่เวอร์ชัน 7 เป็นต้นมา
Code Snippets พร้อมใช้งาน
@props(['title' => null])
<div class="card shadow-sm mb-4">
@if ($title)
<div class="card-header fw-bold">
{{ $title }}
</div>
@endif
<div class="card-body">
{{ $slot }}
</div>
</div>@props([
'label' => '',
'name',
'type' => 'text',
'value' => '',
'placeholder' => '',
'required' => false,
])
<div class="mb-3">
@if ($label)
<label for="{{ $name }}" class="form-label">
{{ $label }}
@if ($required)
<span class="text-danger">*</span>
@endif
</label>
@endif
<input
id="{{ $name }}"
type="{{ $type }}"
name="{{ $name }}"
value="{{ $value }}"
placeholder="{{ $placeholder }}"
{{ $attributes->merge([
'class' => 'form-control' . ($errors->has($name) ? ' is-invalid' : '')
]) }}
>
@error($name)
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div><x-card title="เพิ่มผู้ใช้งาน">
<form action="/users" method="POST">
@csrf
<x-form.input
label="ชื่อ-นามสกุล"
name="name"
type="text"
:value="old('name')"
placeholder="กรอกชื่อ-นามสกุล"
required
/>
<x-form.input
label="อีเมล"
name="email"
type="email"
:value="old('email')"
placeholder="example@email.com"
required
/>
<x-form.input
label="รหัสผ่าน"
name="password"
type="password"
placeholder="อย่างน้อย 8 ตัวอักษร"
required
/>
<button type="submit" class="btn btn-primary">
บันทึก
</button>
</form>
</x-card>สรุป
Blade Component เป็นหนึ่งในเครื่องมือที่ทรงพลังที่สุดของ Laravel แต่กลับถูกมองข้ามบ่อยมาก สิ่งที่คุณได้รับทันทีหลังเริ่มใช้:
- โค้ดสะอาดขึ้น — ไม่มี HTML ซ้ำกระจายทั่วทุก View
- แก้ครั้งเดียว มีผลทุกหน้า — แก้ Component เดียว ทุกหน้า update พร้อมกัน
- UI มีมาตรฐานเดียวกัน — ทั้งทีมใช้ Component เดียวกัน ดีไซน์จึงสม่ำเสมอ
- ทำงานเป็นทีมง่ายขึ้น — ต่างคนต่างพัฒนา Component แล้วนำมาประกอบกัน
"ถ้าคุณยังใช้ @include เพื่อแยก UI ทุกอย่างอยู่ ลองเปลี่ยนบางส่วนมาเป็น Blade Component แล้วคุณจะเริ่มเห็นว่า Laravel ช่วยจัดระเบียบโค้ดได้มากกว่าที่คิด"
ความคิดเห็น
แสดงความคิดเห็น