การทำ Components และ Slots ใน Laravel
การใช้งาน Components ใน laravel

สำหรับการออกแบบเว็บไซต์นั้น การที่ทำให้ code ของเรา Reuse ได้ก็เป็นเรื่องที่ดีไม่ใช่น้อย เพราะนอกจากจะเรียกใช้งานได้บ่อยๆแล้วเวลาแก้ไข สามารถแก้ไขที่จุดเดียวเปลี่ยนทั้ง Application ได้เลย วันนี้จะขอมาพูดถึงเรื่อง Components & Slots ใน Laravel กันครับ และหัวข้อนี้จะเกี่ยวกับ HTML, PHP, Bootstrap สำหรับ document หรือวิธีการที่พูดถึงในบทความนี้จะเป็น Laravel version 6.x นะครับ

เวลาที่เราทำหน้าเว็บขึ้นมาซักหนึ่งหน้าก็มักจะมี HTML บางตัวที่ต้องไปแสดงผลหลายๆที่ ส่วนใหญ่เราก็จะใช้วิธี copy HTML นั้นๆไปวางในแต่ละหน้า ถ้า Application ของเราไม่ใหญ่มากก็ไม่ใช่ปัญหาซักเท่าไหร่ แต่ถ้าเว็บมันมีโอกาศโตขึ้นเรื่อยๆ ส่วนประกอบต่างๆเพิ่มขึ้นเรื่อยๆแน่นอนว่าเวลาแก้ไขย่อมมีความผิดพลาด แก้ไขไม่ครบ สี Component ไม่ตรงกันบ้าง ยกตัวอย่างจาก Component Alerts ของ Bootstrap กัน หน้าตามันก็ประมานนี้

เริ่มใช้งานแบบง่ายๆ

ผมขอยกตัวอย่าง Alert สีแดง จะมีหน้าตา HTML แบบนี้

<div class="alert alert-danger" role="alert">
  A simple danger alert—check it out!
</div>

ถ้าเรานำไปใช้งานเพื่อแจ้งเตือนผู้ใช้ กรณีที่กรอกอีเมล รหัสผ่าน หรือทำอะไรผิดพลาดก็ตาม ลองนึกภาพตามดูครับ น่าจะวางไว้หลายๆที่ในเว็บไซต์เลย แล้วถ้าเกิดวันนึงเราอยากเพิ่ม class ใน html เราก็ต้องไปตามแก้ทุกหน้า เพราะฉะนั้นเราจะมาทำให้มันเป็น component กันจะได้เอาไปใช้ได้สะดวกทุกที่ ทุกเวลา ขั้นแรกให้เราทำการสร้างไฟล์ Blade ปกติครับ เช่น alert.blade.php ให้เราลบข้อความออกและแทนที่ด้วยตัวแปร $slot จะได้หน้าตาแบบนี้

<!-- /resources/views/alert.blade.php -->

<div class="alert alert-danger">
    {{ $slot }}
</div>

เวลาเราจะนำไปใช้งานในไฟล์ Blade หน้าอื่นๆก็ใช้วิธีการนี้

<!-- /resources/views/home.blade.php -->

@component('alert')
    <strong>Whoops!</strong> Something went wrong!
@endcomponent

ใน block ของ component จะมีข้อความที่เราเพิ่มเข้าไปซึ่งเจ้าตัวข้อความนี้เวลาหน้าเว็บถูกเรียกใช้มันจะนำข้อความไปแทนที่ {{ $slot }} ทำให้เราสามารถเปลี่ยนคำ หรือใส่ HTML ใหม่ๆเข้าไปได้

ใช้งานแบบ Advance ขึ้นอีกนิด

กรณีที่เราต้องการความ Advance เพิ่มอีกนิดเราสามารถทำ slot name ให้กับ component ของเราได้ด้วยโดยการเพิ่ม code นิดหน่อยแบบนี้

<!-- /resources/views/alert.blade.php -->

<div class="alert alert-danger">
    <div class="alert-title">{{ $title }}</div>

    {{ $slot }}
</div>

สังเกตุว่าเราเพิ่มตัวแปร $title เข้ามา และ ยังมี $slot อยู่เหมือนเดิม จำไว้เสมอว่าข้อความที่เราใส่ลงไปใน block @component จะไปแทนที่ $slot เสมอ ส่วน $title เราสามารถแทนที่ด้วย @slot(‘name’) เราก็จะได้หน้าตาแบบนี้

@component('alert')
    @slot('title')
        Forbidden
    @endslot

    You are not allowed to access this resource!
@endcomponent

ตัว @slot(‘title’) จะเข้าไปแทนที่ $title ส่วนข้อความนอก @slot นั้นจะเข้าไปแทนที่ตัวแปร $slot เช่นเดิม เราสามารถที่จะทำ component หลายๆตัวไว้ใช้งานได้

ส่งตัวแปรเข้า Components

ถ้าเราอยากส่งตัวแปรอะไรบ้างอย่างไปที่ component โดยที่ไม่ผ่าน $slot เราสามารถใส่ param ตัวที่ 2 ของ @component ได้แบบนี้

@component('alert', ['foo' => 'bar'])
    @slot('title')
        Forbidden
    @endslot

    Hello, {{ $foo }}
    // Hello, bar
@endcomponent

การตั้งชื่อ Component

แน่นอนว่าเราคงไม่อยากพิมพ์ @component(‘alert’) ยาวๆตลอดแน่นอน และถ้าเรายิ่งเอาตัว component เข้าไปวางลึกๆแบบนี้ resources/views/components/alert.blade.php เราก็ต้องเขียน @component(‘components.alert’) เพื่อให้ง่ายต่อการใช้งานเราสามารถตั้งชื่อใหม่ หรือสร้าง directive มาใช้งานได้โดยเข้าไปที่ไฟล์ AppServiceProvider และใส่ code นี้ลงไป

<!-- app/Providers/AppServiceProvider.php -->

use Illuminate\Support\Facades\Blade;

public function boot()
{
    Blade::component('components.alert', 'alert');
}

code ด้านบนเป็นการอ้างถึงไฟล์ใน components/alert.blade.php และ ทำการตั้งชื่อใหม่เป็น alert เวลานำมาใช้งานก็ทำแบบนี้ได้เลย

@alert
    You are not allowed to access this resource!
@endalert

เรายังสามารถส่งตัวแปรเข้าไปได้เหมือนเดิม

@alert(['foo' => 'bar'])
    You are not allowed to access this resource!
@endalert

วิธีจะยุ่งยากตอนเริ่มต้น setup project บ้าง แต่ถ้าเราทำบ่อยๆ จะชินและตั้งค่าเร็วขึ้นครับ รวมถึงถ้ามีการอ้างถึง component หรือ designer อยากแก้เราก็สามารถแก้ไขที่เดียวและเปลี่ยนทั้งโปรเจคได้เลย

Reference

ขอบคุณทุกคนที่ติดตาม และอ่านบทความของผมครับ หากใครมีคำถามหรืออยากให้ผมเขียนเกี่ยวกับเรื่องอะไรเพิ่มเติม สามารถแสดงความคิดเห็นไว้ที่ใต้บทความ หรือส่งเรื่องเข้ามาที่ Email ได้เลยครับ หัวข้อไหนน่าสนใจ ผมจะหยิบมาเขียนบทความให้ได้อ่านกันเรื่อยๆครับ

Scroll to Top