【Laravel實戰】15分鐘搞懂Livewire的組件事件

【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>

分享這篇文章:

關聯文章:

訂閱電子報,索取 Laravel 學習手冊

價值超過 3000 元,包含常用 Laravel 語法與指令!

Laravel 百萬年薪特訓營

從最基礎的 PHP 語法開始,包含所有你該知道的網頁基礎知識,連同 Laravel 從零開始一直到實戰,最後還將告訴你如何找好工作,讓你及早擁有百萬年薪