使用 Livewire 之後,在 Layout 上會改用 component 的 $slot
方式來綁定 Livewire 渲染的畫面。這項改動會導致原本 Controller Blade 在 @extends('layouts.app')
時會報錯 ErrorException Undefined variable: slot
。
為了不用把一樣的 Layout 拆成兩個各自維護,以下整理了幾個不同的方法與思考方向。
這個方法是把 Livewire 改成透過 extends 去產生畫面,因此如果是原有專案則可以不用改變 Layout 的設置,新的專案的話則必須把 {{ $slot }}
替換成 @yield()
。之後在每個 Livewire 在 render() 額外加一行 ->extends()
去指定要使用哪個 Layout,這樣就完成了。
而在 Controller Blade 方面,則可以不用做任何改動就可以完成兼容。
# Layout
<head>
@livewireStyles
</head>
<body>
@yield('content')
@livewireScripts
</body>
# Livewire
public function render()
{
return view('livewire.show-posts')
->extends('layouts.app');
}
如果有多個 @yield
可以透過 ->section()
來指定是哪一個:
public function render()
{
return view('livewire.show-posts')
->extends('layouts.app')
->section('main');
}
這個方法比較適合用在舊的專案上,只是在大量使用 Livewire 的時候會覺得很煩要一直加用 extends
。其餘部分是都還 ok,也不會影響到原本的專案。
優點:
缺點:
->extends()
由於 $slot
是 Laravel Component 中的使用方法,當元件中沒有被指定的內容都會被丟到 $slot
中,像是:
# component - 'demo'
<div>
<p>Show Slot:</p>
{{ $slot }}
</div>
# blade
<x-demo>
<p>CLICK the button NOW !</p>
<button>Click Me</button>
</x-demo>
# 實際渲染
<div>
<p>Show Slot:</p>
<p>CLICK the button NOW !</p>
<button>Click Me</button>
</div>
因此可以透過這個方式把原本的 Layout 給它弄成 Component 的方式,就可以同時兼容 Livewire 與原本的 blade。
php artisan make:component Layout
由於 Livewire 默認是使用 layouts.app
,因此只要替換在 Component 中的 render() 原本所指定的 view 就好。
public function render()
{
return view('components.layout');
}
替換成在 views/layouts
下的檔案
public function render()
{
return view('layouts.app');
}
<x-layout>
之後在原本的 Blade 頁面所使用的 @extends('layouts.app')
就可以不用加了,之後都改用 <x-layout>
就可以將該頁面的東西放入 Layout 中啦!
<x-layout>
...
</x-layout>
比較適合新建的全 Livewire 專案,哪天突然有需要用到從 Controller 直接產生畫面的需求,就可以在不影響 Livewire 運行的情況下完美兼容。
優點:
缺點:
主要也是要看專案哪方面用比較多來選擇兼容的方法,如果是原本的專案要追加 Livewire 的話,用第一種方法就能在不修改其他部分就能夠兼容,還可以不用重構。
而新的專案如果是使用 Livewire 的話基本上是不會使用到 Controller 啦。但是萬一有遇到要使用的場景再補上方法二的方式就可以了,不過用過了 Livewire 誰還回得去呢 XDD!