iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Modern Web

Laravel Livewire:不用 Vue 跟 jQuery 居然也能讓 Laravel 的畫面動起來 ?!系列 第 4

Day 04 | 渲染元件

要渲染 Livewire 元件也非常簡單,主要會分成兩種常用的方法,以下會分別對照 官方文件 來做示範。

作爲元件引入

作為頁面中的元件引入使用,可以當作輸入表單、圖片上傳、按鈕或是任何想要存入資料庫的同時但又不需要將頁面重新整理的功能。引入的方式可以像 Vue.js 的 Component 或是傳統 Laravel 的 @ 用法,就照你的習慣挑一種就好,用起來都是一樣的。

使用 <livewire> tag
<div>
    <livewire:show-posts />
</div>
使用 @livewire
@livewire('show-posts')

如果要傳值的話

這邊其實就跟 Vue.js 傳值給子元件的方法一樣。

<livewire:show-post :post="$post">
//
@livewire('show-post', ['post' => $post])

之後在 app/Http/Livewire/ShowPost.php 中就可以宣告一個同名的變數來接這個值

class ShowPost extends Component
{
    public $post;
 
    ...
}

作為頁面引入(嵌套路由)

如果想要讓整個頁面幾乎都是 Livewire 那就可以用這個方法。這個方法跟 Vue 平常會用的嵌套路由一樣,也跟 Laravel 原先的 @yield 用法一樣。讓最外層的 Layout 固定像是上方的 Navbar 或是底下的 Footer 等等,並透過路由來切換主要的內容頁面。

首先都要先將元件引入在 Route 中,與原本的 Controller 一樣。

# routes/web.php
...
use App\Http\Livewire\ShowPosts;
...
Route::get('/post', ShowPosts::class);

注意:有些專案會在 app\Providers\RouteServiceProvider.php 中啟用 namespace,目的是在 Route 中呼叫 Controller 時都可以少打前面的 App\Http\Controller,但這樣會造成你在引入 Livewire 時導致路徑會出錯。而如果將 namespace 改成 App\Http 則會導致內建的 Auth::route() 發生錯誤,所以這邊建議是不要啟用它。

接著在 Layout 或是任一當作最外層的頁面加上 {{ $slot }},預設都用 $slot 但當然也是可以手動去改這個變數的名稱,但後面渲染時也要自己再改就是了。

<head>
    @livewireStyles
</head>
<body>
    {{ $slot }}
 
    @livewireScripts
</body>

等同 Vue.js 的 <router-view></router-view>

接著在 app\http\Livewire\ShowPosts.php 中選擇要使用的 layout

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

如果你的 $slot 有自己改名字的話,那就要再加一行來跟它說叫什麼名字。

public function render()
{
    return view('livewire.show-posts')
        ->layout('layouts.base')
        ->slot('main');
}

如果要原本 @yield 共用

有些頁面的內容可能不會需要用到 Livewire 這時候就會用回原本 Controller 或是在 Route 直接回傳 view 的方法,因此 Livewire 也支援 ->extends() 的用法,而不是使用上面的 ->layout()

public function render()
{
    return view('livewire.show-posts')
        ->extends('layouts.app');
}

如果要使用 @section 也是可以的

public function render()
{
    return view('livewire.show-posts')
        ->extends('layouts.app')
        ->section('body');
}

透過路由傳參數

一些功能中,我們可能會依照ID來產生對應的頁面內容,這時候就需要透過路由傳遞參數給頁面,像是 /post/210831001。在路由中用法也跟原先傳遞參數給 Controller 的方式一樣:

Route::get('/post/{post_id}', ShowPost::class);

之後在 Livewire 中宣告的 pubic $post_id; 就會自己拿到值囉。

class ShowPost extends Component
{
    public $post_id;
}

進階一點寫法的話還可以直接幫你綁定 Model ,這邊的 Post $post 是直接代替了 $post = Post::find($id);。因此後面就可以直接用 $post->id$post->save() 等等直接操作該筆資料的內容了!!

Route::get('/post/{post}', ShowPost::class);
class ShowPost extends Component
{
    public Post $post;
}

注意:官方文件指出需要 PHP 7.4 才支援自動綁定的功能,不然還是要自己寫在 mount() 中,如下:

class ShowPost extends Component
{
    public $post;
 
    public function mount(Post $post)
    {
        $this->post = $post;
    }
}

上一篇
Day 03 | 透過指令建立元件
下一篇
Day 05 | 資料綁定(一)
系列文
Laravel Livewire:不用 Vue 跟 jQuery 居然也能讓 Laravel 的畫面動起來 ?!34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言