Đang tải...

Cách sử dụng Custom Slots trong các component Livewire toàn trang

Trong bài viết này, tôi sẽ mô tả một mẹo không được ghi chép nhưng lại rất hữu ích để sử dụng slots trong Livewire.

Nếu bạn đang sử dụng các thành phần toàn trang đầy đủ trong Livewire, thành phần của bạn sẽ trông giống như thế này:

class ShowPosts extends Component
{
    ...
    public function render(): View
    {
        return view('livewire.show-posts')
            ->layout('layouts.base');
    }
}

Sau đó, livewire.show-posts tệp của bạn chứa nội dung của thành phần này. layouts.base Tệp có thể trông giống như thế này (được đơn giản hóa một chút):

<x-layouts.app>
    <x-header />
 
    <div>
        <main>
            {{ $slot }}
        </main>
 
        <x-sidebar>
           <!-- Some hardcoded sidebar code -->
        </x-sidebar>
 
        <div>
            <!-- Some other stuff -->
       </div>
    </div>
 
    <x-footer />
</x-layouts.app>

Điều này hoạt động rất tốt. Livewire sẽ tự động đưa nội dung của livewire.show-posts tệp vào biến $slot và sẽ hiển thị trên trang.

Nhưng nếu bạn muốn thêm một số mã động vào thanh bên thì sao ? Mã từ Livewire sẽ được truyền vào biến $slot, vì vậy hiện tại bạn không thể đặt một số mã vào thành phần<x-sidebar>. Để giải quyết vấn đề này, tất nhiên bạn có thể di chuyển {{ $slot }} lên một cấp cao hơn và đặt toàn bộ mã với <main><x-sidebar><div> vào mỗi thành phần Livewire. Tuy nhiên, điều đó sẽ khá khó khăn, vì điều đó có nghĩa là chúng ta sẽ phải xây dựng lại thanh bên và lặp lại Some other stuff trên mọi trang.

May mắn thay, Laravel có một giải pháp tốt cho vấn đề đó: slots. Slots cho phép bạn định nghĩa code và code đó sẽ được gán cho một biến khác với $slot. Hóa ra điều này cũng hoạt động với Livewire. Hãy cùng xem nhé.

Đầu tiên, hãy vào layouts.base tệp của bạn và cập nhật nó để sử dụng biến có tên là $sidebar:

@props([
    'sidebar' => null,
])
 
<x-layouts.app>
    <x-header />
 
    <div>
        <main>
            {{ $slot }}
        </main>
 
        <x-sidebar>
           <!-- Some hardcoded sidebar code -->
 
           @if($sidebar)
             {{ $sidebar }}
           @endif
        </x-sidebar>
 
        <div>
            <!-- Some other stuff -->
       </div>
    </div>
 
    <x-footer />
</x-layouts.app>

Sau đó, trong tệp livewire.show-posts của bạn, bạn có thể triển khai sidebar slot:

<div>
    <!-- Component code -->
</div>
 
<!-- The slot can be defined outside the Livewire root tag. -->
<x-slot:sidebar>
     <!-- Sidebar code -->
</x-slot:sidebar>

Xin chúc mừng! Tải lại trang và bây giờ bạn sẽ thấy mã thanh bên được đặt trong thanh bên và mã chính được đặt trong vùng trang chính.

Những lưu ý

Tôi nghĩ mẹo trên rất hữu ích, nhưng có một nhược điểm cần lưu ý. Nhược điểm đó là mã trong các ô tùy chỉnh là tĩnh, do đó, nó sẽ không được tải lại khi bạn thực hiện hành động trên trang Livewire. Do đó, bạn không nên bao gồm mã có ý định thực hiện điều gì đó với thành phần Livewire, như wire:click. (Nếu bạn thực sự cần sử dụng wire:click, bạn có thể sử dụng JavaScript thuần túy và sử dụng window.Livewire.call(). Tuy nhiên, mã sẽ không được làm mới.) 

Do đó, bạn nên nhớ rằng điều này hoạt động tuyệt vời đối với các trang tĩnh. Nếu bạn cần cập nhật mã trong các slot , bạn có thể cân nhắc tải lại trang bằng cách chuyển hướng đến route ban đầu.

Chúc bạn code vui vẻ!