【Laravel實戰】15分鐘搞懂Livewire的組件事件
Livewire 組件們能夠透過全域事件系統來進行溝通。只要兩個 Livewire 組件位在同一個頁面,它們就能透過事件和偵聽器來溝通 首先來看看該怎麼發送事件,這裡有多種方法能從 Livewire 組件去發送事件
方法 1: 從視圖
<button wire:click="$emit('postAdded')">
方法 2: 從組件方法
$this->emit('postAdded’);
方法 3: 從全域JS函式
<script>
Livewire.emit('postAdded')
</script>
事件偵聽器
事件偵聽器為註冊於你的 Livewire 組件內的 $listeners 屬性,事件偵聽器是以鍵值對的形式,鍵為所要偵聽的事件,而值則是要呼叫的組件方法
class ShowPosts extends Component
{
public $postCount;
protected $listeners = ['postAdded' => 'incrementPostCount'];
public function incrementPostCount()
{
$this->postCount = Post::count();
}
}
以這些程式碼案例來說明,當其他同一頁面的組件發出一個 postAdded 事件,這個組件將會抓取該事件並呼叫自己的 incrementPostCount()
如果事件名稱與方法名稱相同的話,你也可以只寫鍵即可。比如protected $listeners = ['postAdded’];
假如你需要偵聽動態事件名,也就是根據不同狀況偵聽對應名稱,你可以拿掉組件的 $listeners 屬性並改以 getListeners() 來達到
class ShowPosts extends Component
{
public $postCount;
protected function getListeners()
{
return ['postAdded' => 'incrementPostCount'];
}
...
}
附帶參數
你能夠在發送事件時附帶參數,我們來看看發送端以及接收端怎麼處理
發送端
$this->emit('postAdded', $post->id);
接收端
class ShowPosts extends Component
{
public $postCount;
public $recentlyAddedPost;
protected $listeners = ['postAdded'];
public function postAdded(Post $post)
{
$this->postCount = Post::count();
$this->recentlyAddedPost = $post;
}
}
事件域
事件域有幾個概念需要了解
其中第一個作用域是 Scoping To Parent Listeners,即針對上層組件
當處理巢狀組件時,有時你只想要發送事件到父組件,而要跳過子組件或者是相鄰組件。這時候 emitUp() 就派上用場了,以下是它的用法
$this->emitUp('postAdded’);
<button wire:click="$emitUp('postAdded')">
第二個作用域是 Scoping To Components By Name,即針對同名組件
有時候你只想要發送一個事件到相同類型的其他組件,這時候 emitTo() 就派上用場了
$this->emitTo('counter', 'postAdded');
<button wire:click="$emitTo('counter', 'postAdded')">
現在當上方設定的按鈕被按下時, "postAdded" 事件將只會被發送給 counter 組件
第三個作用域是 Scoping To Self,即針對自己
有時候你只想要發送一個事件給自己,這時候 emitSelf() 就派上用場了
$this->emitSelf('postAdded');
<button wire:click="$emitSelf('postAdded')”>
現在當上方設定的按鈕被按下時,"postAdded" 事件將只會被發送給發出事件的自己
以上三種作用域能幫助你將事件發送給限定的組件而非全體,在進行較為複雜的系統開發時很有用,一定要學起來喔!
在JS偵聽事件
接下來聊聊你該如何在JS裡頭去偵聽事件,Livewire 允許你在 JS 裡去註冊事件偵聽器,像這樣:
<script>
Livewire.on('postAdded', postId => {
alert('A post was added with the id of: ' + postId);
})
</script>
這個特色是極為強大的,利用這個技巧你就能夠透過事件來呼叫 JS 腳本。比如當 Livewire 執行某些任務時在你的應用跳出一個 popup 視窗。這是其中一種透過 Livewire 用來橋接 PHP 與 JS 的技巧
甚至你還可以在 PHP 程式裡頭去派發瀏覽器事件,也就是說 Livewire 允許你去發送瀏覽器視窗事件,像這樣:
$this->dispatchBrowserEvent('name-updated', ['newName' => $value]);
接著你就能夠利用 JS 來偵聽這個視窗事件
<script>
window.addEventListener('name-updated', event => {
alert('Name updated to: ' + event.detail.newName);
})
</script>
如果你熟悉前端的 AlpineIS 框架的話,它允許你輕鬆的在HTML裡頭去偵聽這些視窗事件
<div x-data="{ open: false }" @name-updated.window="open = false">
<!-- Modal with a Livewire name update form -->
</div>



