跳到內容

Blade 樣板

簡介

Blade 是一個簡單但功能強大的樣板引擎,包含在 Laravel 中。與某些 PHP 樣板引擎不同,Blade 不會限制你在樣板中使用純 PHP 程式碼。實際上,所有 Blade 樣板都會被編譯成純 PHP 程式碼並快取,直到它們被修改為止,這表示 Blade 幾乎不會為你的應用程式增加任何負擔。Blade 樣板檔案使用 .blade.php 副檔名,通常儲存在 resources/views 目錄中。

可以使用全域 view 輔助函數從路由或控制器返回 Blade 視圖。當然,如 視圖 文件中所述,可以使用 view 輔助函數的第二個參數將資料傳遞到 Blade 視圖

Route::get('/', function () {
return view('greeting', ['name' => 'Finn']);
});

使用 Livewire 加強 Blade

想要將你的 Blade 樣板提升到新的層次,並輕鬆建立動態介面嗎?請查看 Laravel Livewire。Livewire 允許你編寫 Blade 組件,這些組件透過通常只能透過 React 或 Vue 等前端框架才能實現的動態功能來增強,提供了一個很好的方法來建構現代、反應式的前端,而無需許多 JavaScript 框架的複雜性、客戶端渲染或建置步驟。

顯示資料

你可以透過將變數包在大括號中來顯示傳遞到 Blade 視圖的資料。例如,假設有以下路由

Route::get('/', function () {
return view('welcome', ['name' => 'Samantha']);
});

你可以像這樣顯示 name 變數的內容

Hello, {{ $name }}.
lightbulb - Laravel 框架

Blade 的 {{ }} echo 語句會自動透過 PHP 的 htmlspecialchars 函數傳送,以防止 XSS 攻擊。

你不僅限於顯示傳遞給視圖的變數內容。你也可以回傳任何 PHP 函數的結果。事實上,你可以將任何你想要的 PHP 程式碼放入 Blade echo 語句中

The current UNIX timestamp is {{ time() }}.

HTML 實體編碼

預設情況下,Blade(以及 Laravel 的 e 函數)會對 HTML 實體進行雙重編碼。如果你想停用雙重編碼,請從 AppServiceProviderboot 方法中呼叫 Blade::withoutDoubleEncoding 方法

<?php
 
namespace App\Providers;
 
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::withoutDoubleEncoding();
}
}

顯示未轉義的資料

預設情況下,Blade {{ }} 語句會自動透過 PHP 的 htmlspecialchars 函數傳送,以防止 XSS 攻擊。如果你不希望你的資料被轉義,你可以使用以下語法

Hello, {!! $name !!}.
exclamation - Laravel 框架

回傳應用程式使用者提供的內容時,請務必小心。在顯示使用者提供的資料時,你通常應該使用轉義的雙大括號語法來防止 XSS 攻擊。

Blade 和 JavaScript 框架

由於許多 JavaScript 框架也使用「大括號」來表示應在瀏覽器中顯示給定的表達式,你可以使用 @ 符號來通知 Blade 渲染引擎該表達式應保持不變。例如

<h1>Laravel</h1>
 
Hello, @{{ name }}.

在此範例中,@ 符號將被 Blade 移除;但是,{{ name }} 表達式將保持 Blade 引擎不變,使其能夠被你的 JavaScript 框架渲染。

@ 符號也可以用來跳脫 Blade 指令

{{-- Blade template --}}
@@if()
 
<!-- HTML output -->
@if()

渲染 JSON

有時,你可能會將陣列傳遞到視圖中,以便將其渲染為 JSON,從而初始化 JavaScript 變數。例如

<script>
var app = <?php echo json_encode($array); ?>;
</script>

但是,你不需要手動呼叫 json_encode,你可以使用 Illuminate\Support\Js::from 方法指令。from 方法接受與 PHP 的 json_encode 函數相同的參數;但是,它會確保結果 JSON 正確轉義,以便包含在 HTML 引號中。from 方法將返回一個字串 JSON.parse JavaScript 語句,該語句會將給定的物件或陣列轉換為有效的 JavaScript 物件

<script>
var app = {{ Illuminate\Support\Js::from($array) }};
</script>

最新版本的 Laravel 應用程式骨架包含一個 Js Facade,它提供在你的 Blade 樣板中方便存取此功能的方式

<script>
var app = {{ Js::from($array) }};
</script>
exclamation - Laravel 框架

你應該只使用 Js::from 方法來將現有變數渲染為 JSON。Blade 樣板基於正規表示式,嘗試將複雜表達式傳遞給指令可能會導致意外失敗。

@verbatim 指令

如果你在樣板的很大一部分中顯示 JavaScript 變數,你可以將 HTML 包裝在 @verbatim 指令中,這樣你就不用在每個 Blade echo 語句前面加上 @ 符號

@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim

Blade 指令

除了樣板繼承和顯示資料之外,Blade 還為常見的 PHP 控制結構(例如條件語句和迴圈)提供了方便的快捷方式。這些快捷方式提供了一種非常簡潔、簡潔的方法來處理 PHP 控制結構,同時仍與其 PHP 對應項目保持熟悉。

If 語句

你可以使用 @if@elseif@else@endif 指令來建構 if 語句。這些指令的功能與其 PHP 對應項相同

@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif

為了方便起見,Blade 還提供了一個 @unless 指令

@unless (Auth::check())
You are not signed in.
@endunless

除了已經討論的條件指令之外,@isset@empty 指令可以用作各自 PHP 函數的方便快捷方式

@isset($records)
// $records is defined and is not null...
@endisset
 
@empty($records)
// $records is "empty"...
@endempty

身份驗證指令

@auth@guest 指令可用於快速判斷目前使用者是否已通過身份驗證或為訪客

@auth
// The user is authenticated...
@endauth
 
@guest
// The user is not authenticated...
@endguest

如果需要,你可以指定在使用 @auth@guest 指令時應檢查的身份驗證守衛

@auth('admin')
// The user is authenticated...
@endauth
 
@guest('admin')
// The user is not authenticated...
@endguest

環境指令

你可以使用 @production 指令來檢查應用程式是否在生產環境中執行

@production
// Production specific content...
@endproduction

或者,你可以使用 @env 指令來判斷應用程式是否在特定環境中執行

@env('staging')
// The application is running in "staging"...
@endenv
 
@env(['staging', 'production'])
// The application is running in "staging" or "production"...
@endenv

區段指令

你可以使用 @hasSection 指令來判斷樣板繼承區段是否具有內容

@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
 
<div class="clearfix"></div>
@endif

你可以使用 sectionMissing 指令來判斷區段是否沒有內容

@sectionMissing('navigation')
<div class="pull-right">
@include('default-navigation')
</div>
@endif

Session 指令

@session 指令可用於判斷是否存在 session 值。如果 session 值存在,則會評估 @session@endsession 指令中的樣板內容。在 @session 指令的內容中,你可以回傳 $value 變數來顯示 session 值

@session('status')
<div class="p-4 bg-green-100">
{{ $value }}
</div>
@endsession

Switch 語句

可以使用 @switch@case@break@default@endswitch 指令來建構 Switch 語句

@switch($i)
@case(1)
First case...
@break
 
@case(2)
Second case...
@break
 
@default
Default case...
@endswitch

迴圈

除了條件語句之外,Blade 還提供了簡單的指令來處理 PHP 的迴圈結構。同樣,每個這些指令的功能都與其 PHP 對應項相同

@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
 
@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach
 
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse
 
@while (true)
<p>I'm looping forever.</p>
@endwhile
lightbulb - Laravel 框架

在迴圈執行 foreach 迴圈時,你可以使用 迴圈變數 來獲取有關迴圈的寶貴資訊,例如你是否在迴圈的第一次或最後一次迭代中。

使用迴圈時,你也可以使用 @continue@break 指令來跳過目前的迭代或結束迴圈

@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
 
<li>{{ $user->name }}</li>
 
@if ($user->number == 5)
@break
@endif
@endforeach

您也可以在指令宣告中加入繼續或中斷的條件。

@foreach ($users as $user)
@continue($user->type == 1)
 
<li>{{ $user->name }}</li>
 
@break($user->number == 5)
@endforeach

迴圈變數

在遍歷 foreach 迴圈時,您的迴圈內可以使用 $loop 變數。這個變數提供了對一些有用資訊的存取,例如目前的迴圈索引,以及這是否是迴圈中的第一次或最後一次迭代。

@foreach ($users as $user)
@if ($loop->first)
This is the first iteration.
@endif
 
@if ($loop->last)
This is the last iteration.
@endif
 
<p>This is user {{ $user->id }}</p>
@endforeach

如果您處於巢狀迴圈中,您可以使用 parent 屬性存取父迴圈的 $loop 變數。

@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is the first iteration of the parent loop.
@endif
@endforeach
@endforeach

$loop 變數還包含各種其他有用的屬性。

屬性 描述
$loop->index 目前迴圈迭代的索引(從 0 開始)。
$loop->iteration 目前迴圈迭代的次數(從 1 開始)。
$loop->remaining 迴圈中剩餘的迭代次數。
$loop->count 正在迭代的陣列中元素的總數。
$loop->first 這是否是迴圈中的第一次迭代。
$loop->last 這是否是迴圈中的最後一次迭代。
$loop->even 這是否是迴圈中的偶數次迭代。
$loop->odd 這是否是迴圈中的奇數次迭代。
$loop->depth 目前迴圈的巢狀層級。
$loop->parent 當在巢狀迴圈中時,父迴圈的變數。

條件式類別 & 樣式

@class 指令會根據條件編譯 CSS 類別字串。該指令接受一個類別陣列,其中陣列的鍵包含您想要加入的類別,而值則是一個布林運算式。如果陣列元素具有數值鍵,則它將始終包含在渲染的類別清單中。

@php
$isActive = false;
$hasError = true;
@endphp
 
<span @class([
'p-4',
'font-bold' => $isActive,
'text-gray-500' => ! $isActive,
'bg-red' => $hasError,
])></span>
 
<span class="p-4 text-gray-500 bg-red"></span>

同樣地,@style 指令可用於有條件地將內嵌 CSS 樣式新增至 HTML 元素。

@php
$isActive = true;
@endphp
 
<span @style([
'background-color: red',
'font-weight: bold' => $isActive,
])></span>
 
<span style="background-color: red; font-weight: bold;"></span>

額外屬性

為了方便起見,您可以使用 @checked 指令輕鬆指示給定的 HTML 核取方塊輸入是否為「已勾選」。如果提供的條件評估為 true,則此指令將輸出 checked

<input
type="checkbox"
name="active"
value="active"
@checked(old('active', $user->active))
/>

同樣地,@selected 指令可用於指示給定的選取選項是否應為「已選取」。

<select name="version">
@foreach ($product->versions as $version)
<option value="{{ $version }}" @selected(old('version') == $version)>
{{ $version }}
</option>
@endforeach
</select>

此外,@disabled 指令可用於指示給定的元素是否應為「已停用」。

<button type="submit" @disabled($errors->isNotEmpty())>Submit</button>

此外,@readonly 指令可用於指示給定的元素是否應為「唯讀」。

<input
type="email"
name="email"
@readonly($user->isNotAdmin())
/>

此外,@required 指令可用於指示給定的元素是否應為「必填」。

<input
type="text"
name="title"
value="title"
@required($user->isAdmin())
/>

包含子視圖

lightbulb - Laravel 框架

雖然您可以自由使用 @include 指令,但 Blade 元件提供了類似的功能,並且比 @include 指令提供了多項優勢,例如資料和屬性綁定。

Blade 的 @include 指令允許您從另一個檢視中包含一個 Blade 檢視。父檢視中可用的所有變數都將提供給包含的檢視。

<div>
@include('shared.errors')
 
<form>
<!-- Form Contents -->
</form>
</div>

即使包含的檢視將繼承父檢視中可用的所有資料,您也可以傳遞一個額外資料的陣列,該陣列應提供給包含的檢視。

@include('view.name', ['status' => 'complete'])

如果您嘗試 @include 一個不存在的檢視,Laravel 將會拋出錯誤。如果您想包含一個可能存在也可能不存在的檢視,您應該使用 @includeIf 指令。

@includeIf('view.name', ['status' => 'complete'])

如果您想在給定的布林運算式評估為 truefalse@include 一個檢視,您可以使用 @includeWhen@includeUnless 指令。

@includeWhen($boolean, 'view.name', ['status' => 'complete'])
 
@includeUnless($boolean, 'view.name', ['status' => 'complete'])

要包含給定檢視陣列中存在的第一個檢視,您可以使用 includeFirst 指令。

@includeFirst(['custom.admin', 'admin'], ['status' => 'complete'])
exclamation - Laravel 框架

您應避免在 Blade 檢視中使用 __DIR____FILE__ 常數,因為它們將參照快取、編譯檢視的位置。

為集合渲染檢視

您可以使用 Blade 的 @each 指令將迴圈和包含合併為一行。

@each('view.name', $jobs, 'job')

@each 指令的第一個參數是要為陣列或集合中的每個元素渲染的檢視。第二個參數是您想要遍歷的陣列或集合,而第三個參數是將分配給檢視中目前迭代的變數名稱。因此,舉例來說,如果您正在遍歷一個 jobs 陣列,通常您會希望在檢視中將每個工作作為 job 變數存取。目前迭代的陣列鍵將在檢視中以 key 變數提供。

您也可以將第四個參數傳遞給 @each 指令。此參數決定如果給定的陣列為空時要渲染的檢視。

@each('view.name', $jobs, 'job', 'view.empty')
exclamation - Laravel 框架

透過 @each 渲染的檢視不會繼承父檢視的變數。如果子檢視需要這些變數,您應該改用 @foreach@include 指令。

@once 指令

@once 指令允許您定義範本的一部分,該部分僅在每個渲染週期中評估一次。這對於使用 堆疊將給定的 JavaScript 推送到頁面的標頭中可能很有用。例如,如果您正在迴圈中渲染給定的 元件,您可能希望僅在第一次渲染元件時才將 JavaScript 推送到標頭中。

@once
@push('scripts')
<script>
// Your custom JavaScript...
</script>
@endpush
@endonce

由於 @once 指令通常與 @push@prepend 指令結合使用,因此為了方便起見,提供了 @pushOnce@prependOnce 指令。

@pushOnce('scripts')
<script>
// Your custom JavaScript...
</script>
@endPushOnce

原始 PHP

在某些情況下,將 PHP 程式碼嵌入到您的檢視中很有用。您可以使用 Blade @php 指令在您的範本中執行一段純 PHP 程式碼。

@php
$counter = 1;
@endphp

或者,如果您只需要使用 PHP 來導入類別,則可以使用 @use 指令。

@use('App\Models\Flight')

可以向 @use 指令提供第二個參數來別名導入的類別。

@use('App\Models\Flight', 'FlightModel')

註解

Blade 也允許您在檢視中定義註解。但是,與 HTML 註解不同,Blade 註解不會包含在您的應用程式傳回的 HTML 中。

{{-- This comment will not be present in the rendered HTML --}}

組件

元件和插槽提供與區段、版面配置和包含類似的優勢;但是,有些人可能會發現元件和插槽的思維模型更容易理解。撰寫元件有兩種方法:基於類別的元件和匿名元件。

要建立基於類別的元件,您可以使用 make:component Artisan 命令。為了說明如何使用元件,我們將建立一個簡單的 Alert 元件。make:component 命令會將元件放置在 app/View/Components 目錄中。

php artisan make:component Alert

make:component 命令也會為元件建立檢視範本。該檢視將放置在 resources/views/components 目錄中。當為您自己的應用程式撰寫元件時,元件會自動在 app/View/Components 目錄和 resources/views/components 目錄中探索到,因此通常不需要進一步的元件註冊。

您也可以在子目錄中建立元件。

php artisan make:component Forms/Input

上面的命令將在 app/View/Components/Forms 目錄中建立一個 Input 元件,並且檢視將放置在 resources/views/components/forms 目錄中。

如果您想建立一個匿名元件(只有 Blade 範本而沒有類別的元件),您可以在叫用 make:component 命令時使用 --view 標記。

php artisan make:component forms.input --view

上面的命令將在 resources/views/components/forms/input.blade.php 建立一個 Blade 檔案,該檔案可以透過 <x-forms.input /> 作為元件渲染。

手動註冊套件元件

當為您自己的應用程式撰寫元件時,元件會自動在 app/View/Components 目錄和 resources/views/components 目錄中探索到。

但是,如果您正在建置使用 Blade 元件的套件,您將需要手動註冊您的元件類別及其 HTML 標籤別名。您通常應該在套件的服務提供者的 boot 方法中註冊您的元件。

use Illuminate\Support\Facades\Blade;
 
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::component('package-alert', Alert::class);
}

一旦您的元件已註冊,就可以使用其標籤別名進行渲染。

<x-package-alert/>

或者,您可以使用 componentNamespace 方法來依照慣例自動載入元件類別。例如,Nightshade 套件可能會有 CalendarColorPicker 元件,它們位於 Package\Views\Components 命名空間中。

use Illuminate\Support\Facades\Blade;
 
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

這將允許使用 package-name:: 語法,透過其供應商命名空間使用套件元件。

<x-nightshade::calendar />
<x-nightshade::color-picker />

Blade 將透過將元件名稱轉換為 Pascal 大小寫來自動偵測與此元件連結的類別。子目錄也支援使用「點」表示法。

渲染組件

若要顯示元件,您可以在其中一個 Blade 範本中使用 Blade 元件標籤。Blade 元件標籤以字串 x- 開頭,後跟元件類別的烤肉串式大小寫名稱。

<x-alert/>
 
<x-user-profile/>

如果元件類別巢狀於 app/View/Components 目錄中較深的位置,您可以使用 . 字元來指示目錄巢狀結構。例如,如果我們假設元件位於 app/View/Components/Inputs/Button.php,我們可以這樣渲染它:

<x-inputs.button/>

如果您想有條件地渲染元件,您可以在您的元件類別上定義一個 shouldRender 方法。如果 shouldRender 方法傳回 false,則不會渲染元件。

use Illuminate\Support\Str;
 
/**
* Whether the component should be rendered
*/
public function shouldRender(): bool
{
return Str::length($this->message) > 0;
}

索引組件

有時元件是元件群組的一部分,您可能希望將相關元件分組在單一目錄中。例如,假設一個具有以下類別結構的「卡片」元件:

App\Views\Components\Card\Card
App\Views\Components\Card\Header
App\Views\Components\Card\Body

由於根 Card 元件巢狀在 Card 目錄中,您可能會期望您需要透過 <x-card.card> 來渲染元件。但是,當元件的檔案名稱與元件的目錄名稱相符時,Laravel 會自動假設該元件是「根」元件,並允許您渲染該元件而無需重複目錄名稱。

<x-card>
<x-card.header>...</x-card.header>
<x-card.body>...</x-card.body>
</x-card>

將資料傳遞給組件

您可以使用 HTML 屬性將資料傳遞到 Blade 元件。硬式編碼的原始值可以使用簡單的 HTML 屬性字串傳遞給元件。PHP 運算式和變數應透過使用 : 字元作為前置詞的屬性傳遞到元件。

<x-alert type="error" :message="$message"/>

您應該在其類別建構函式中定義元件的所有資料屬性。元件上的所有公開屬性都會自動提供給元件的檢視。沒有必要從元件的 render 方法將資料傳遞給檢視。

<?php
 
namespace App\View\Components;
 
use Illuminate\View\Component;
use Illuminate\View\View;
 
class Alert extends Component
{
/**
* Create the component instance.
*/
public function __construct(
public string $type,
public string $message,
) {}
 
/**
* Get the view / contents that represent the component.
*/
public function render(): View
{
return view('components.alert');
}
}

當您的元件被渲染時,您可以透過依名稱輸出來顯示元件的公開變數內容。

<div class="alert alert-{{ $type }}">
{{ $message }}
</div>

大小寫

元件建構函式引數應使用 camelCase 指定,而當在 HTML 屬性中參照引數名稱時,應使用 kebab-case。例如,給定以下元件建構函式:

/**
* Create the component instance.
*/
public function __construct(
public string $alertType,
) {}

可以像這樣將 $alertType 引數提供給元件:

<x-alert alert-type="danger" />

簡短屬性語法

在將屬性傳遞給元件時,您也可以使用「簡短屬性」語法。這通常很方便,因為屬性名稱經常與它們對應的變數名稱相符。

{{-- Short attribute syntax... --}}
<x-profile :$userId :$name />
 
{{-- Is equivalent to... --}}
<x-profile :user-id="$userId" :name="$name" />

逸出屬性渲染

由於某些 JavaScript 框架(例如 Alpine.js)也使用冒號前綴的屬性,您可以使用雙冒號 (::) 前綴來告知 Blade 該屬性不是 PHP 表達式。例如,給定以下組件:

<x-button ::class="{ danger: isDeleting }">
Submit
</x-button>

以下 HTML 將由 Blade 渲染:

<button :class="{ danger: isDeleting }">
Submit
</button>

組件方法

除了可以供組件模板使用的公開變數之外,還可以調用組件上的任何公開方法。例如,假設有一個組件具有 isSelected 方法:

/**
* Determine if the given option is the currently selected option.
*/
public function isSelected(string $option): bool
{
return $option === $this->selected;
}

您可以通過調用與方法名稱匹配的變數,從組件模板中執行此方法:

<option {{ $isSelected($value) ? 'selected' : '' }} value="{{ $value }}">
{{ $label }}
</option>

在組件類別中存取屬性和插槽

Blade 組件還允許您在類別的 render 方法內存取組件名稱、屬性和插槽。但是,為了存取此資料,您應該從組件的 render 方法返回一個閉包:

use Closure;
 
/**
* Get the view / contents that represent the component.
*/
public function render(): Closure
{
return function () {
return '<div {{ $attributes }}>Components content</div>';
};
}

您的組件 render 方法返回的閉包還可以接收一個 $data 陣列作為其唯一參數。此陣列將包含多個提供有關組件資訊的元素:

return function (array $data) {
// $data['componentName'];
// $data['attributes'];
// $data['slot'];
 
return '<div {{ $attributes }}>Components content</div>';
}
exclamation - Laravel 框架

$data 陣列中的元素絕不應直接嵌入到 render 方法返回的 Blade 字串中,因為這樣做可能會允許透過惡意屬性內容遠端執行程式碼。

componentName 等於在 x- 前綴之後的 HTML 標籤中使用的名稱。因此 <x-alert />componentName 將會是 alertattributes 元素將包含 HTML 標籤上存在的所有屬性。slot 元素是一個 Illuminate\Support\HtmlString 實例,其中包含組件插槽的內容。

閉包應返回字串。如果返回的字串對應於現有視圖,則將呈現該視圖;否則,返回的字串將被評估為內聯 Blade 視圖。

其他依賴項

如果您的組件需要來自 Laravel 的服務容器的依賴項,您可以在任何組件的資料屬性之前列出它們,並且它們將會自動由容器注入:

use App\Services\AlertCreator;
 
/**
* Create the component instance.
*/
public function __construct(
public AlertCreator $creator,
public string $type,
public string $message,
) {}

隱藏屬性/方法

如果您想要防止某些公開方法或屬性作為變數公開給組件模板,您可以將它們添加到組件上的 $except 陣列屬性中:

<?php
 
namespace App\View\Components;
 
use Illuminate\View\Component;
 
class Alert extends Component
{
/**
* The properties / methods that should not be exposed to the component template.
*
* @var array
*/
protected $except = ['type'];
 
/**
* Create the component instance.
*/
public function __construct(
public string $type,
) {}
}

組件屬性

我們已經研究過如何將資料屬性傳遞給組件;但是,有時您可能需要指定其他 HTML 屬性,例如 class,這些屬性不是組件正常運作所需的資料的一部分。通常,您希望將這些額外的屬性傳遞到組件模板的根元素。例如,假設我們要像這樣渲染一個 alert 組件:

<x-alert type="error" :message="$message" class="mt-4"/>

所有不屬於組件建構函式一部分的屬性都會自動添加到組件的「屬性包」中。此屬性包會透過 $attributes 變數自動提供給組件。所有屬性都可以在組件內透過回應此變數來渲染:

<div {{ $attributes }}>
<!-- Component content -->
</div>
exclamation - Laravel 框架

目前不支援在組件標籤中使用 @env 等指令。例如,<x-alert :live="@env('production')"/> 將不會被編譯。

預設/合併屬性

有時您可能需要為屬性指定預設值,或將其他值合併到某些組件的屬性中。為此,您可以使用屬性包的 merge 方法。此方法對於定義一組應始終套用至組件的預設 CSS 類別特別有用:

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>

如果我們假設此組件的使用方式如下:

<x-alert type="error" :message="$message" class="mb-4"/>

組件的最終渲染 HTML 將如下所示:

<div class="alert alert-error mb-4">
<!-- Contents of the $message variable -->
</div>

有條件地合併類別

有時,您可能希望在給定條件為 true 時合併類別。您可以透過 class 方法完成此操作,該方法接受一個類別陣列,其中陣列索引包含您要新增的類別或多個類別,而值是布林值表達式。如果陣列元素具有數字索引,則它將始終包含在渲染的類別列表中:

<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}>
{{ $message }}
</div>

如果您需要將其他屬性合併到您的組件上,您可以將 merge 方法鏈接到 class 方法:

<button {{ $attributes->class(['p-4'])->merge(['type' => 'button']) }}>
{{ $slot }}
</button>
lightbulb - Laravel 框架

如果您需要在其他不應接收合併屬性的 HTML 元素上有條件地編譯類別,您可以使用@class 指令

非類別屬性合併

合併非 class 屬性的屬性時,提供給 merge 方法的值將被視為該屬性的「預設」值。但是,與 class 屬性不同,這些屬性不會與注入的屬性值合併。相反地,它們將被覆寫。例如,button 組件的實作可能如下所示:

<button {{ $attributes->merge(['type' => 'button']) }}>
{{ $slot }}
</button>

若要使用自訂 type 渲染按鈕組件,可以在使用組件時指定它。如果未指定類型,則將使用 button 類型:

<x-button type="submit">
Submit
</x-button>

在此範例中,button 組件的渲染 HTML 將會是:

<button type="submit">
Submit
</button>

如果您希望 class 以外的屬性將其預設值和注入值連接在一起,您可以使用 prepends 方法。在此範例中,data-controller 屬性將始終以 profile-controller 開頭,任何其他注入的 data-controller 值都將放置在此預設值之後:

<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
{{ $slot }}
</div>

擷取和篩選屬性

您可以使用 filter 方法篩選屬性。此方法接受一個閉包,如果您希望將屬性保留在屬性包中,則該閉包應返回 true

{{ $attributes->filter(fn (string $value, string $key) => $key == 'foo') }}

為了方便起見,您可以使用 whereStartsWith 方法來擷取索引以給定字串開頭的所有屬性:

{{ $attributes->whereStartsWith('wire:model') }}

相反地,可以使用 whereDoesntStartWith 方法來排除所有索引以給定字串開頭的屬性:

{{ $attributes->whereDoesntStartWith('wire:model') }}

使用 first 方法,您可以渲染給定屬性包中的第一個屬性:

{{ $attributes->whereStartsWith('wire:model')->first() }}

如果您想檢查組件上是否存在屬性,您可以使用 has 方法。此方法將屬性名稱作為其唯一參數,並返回一個布林值,指示屬性是否存在:

@if ($attributes->has('class'))
<div>Class attribute is present</div>
@endif

如果將陣列傳遞給 has 方法,則該方法將確定組件上是否存在所有給定的屬性:

@if ($attributes->has(['name', 'class']))
<div>All of the attributes are present</div>
@endif

可以使用 hasAny 方法來確定組件上是否存在任何給定的屬性:

@if ($attributes->hasAny(['href', ':href', 'v-bind:href']))
<div>One of the attributes is present</div>
@endif

您可以使用 get 方法擷取特定屬性的值:

{{ $attributes->get('class') }}

保留關鍵字

依預設,某些關鍵字保留供 Blade 內部使用,以渲染組件。以下關鍵字不能在您的組件中定義為公開屬性或方法名稱:

  • data
  • render
  • resolveView
  • shouldRender
  • view
  • withAttributes
  • withName

插槽

您通常需要透過「插槽」將其他內容傳遞給您的組件。組件插槽透過回應 $slot 變數來渲染。為了探索此概念,我們假設一個 alert 組件具有以下標記:

<!-- /resources/views/components/alert.blade.php -->
 
<div class="alert alert-danger">
{{ $slot }}
</div>

我們可以透過將內容注入到組件中,將內容傳遞給 slot

<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>

有時,組件可能需要在組件內的不同位置渲染多個不同的插槽。讓我們修改我們的 alert 組件,以允許注入「標題」插槽:

<!-- /resources/views/components/alert.blade.php -->
 
<span class="alert-title">{{ $title }}</span>
 
<div class="alert alert-danger">
{{ $slot }}
</div>

您可以使用 x-slot 標籤定義具名插槽的內容。任何不在明確的 x-slot 標籤內的內容都將在 $slot 變數中傳遞給組件:

<x-alert>
<x-slot:title>
Server Error
</x-slot>
 
<strong>Whoops!</strong> Something went wrong!
</x-alert>

您可以調用插槽的 isEmpty 方法來確定插槽是否包含內容:

<span class="alert-title">{{ $title }}</span>
 
<div class="alert alert-danger">
@if ($slot->isEmpty())
This is default content if the slot is empty.
@else
{{ $slot }}
@endif
</div>

此外,可以使用 hasActualContent 方法來確定插槽是否包含任何不是 HTML 註解的「實際」內容:

@if ($slot->hasActualContent())
The scope has non-comment content.
@endif

範圍插槽

如果您使用過像 Vue 這樣的 JavaScript 框架,您可能熟悉「範圍插槽」,這讓您可以從組件內存取插槽內的資料或方法。您可以在 Laravel 中透過在您的組件上定義公開方法或屬性,並透過 $component 變數存取您插槽內的組件來實現類似的行為。在此範例中,我們將假設 x-alert 組件在其組件類別上定義了一個公開的 formatAlert 方法:

<x-alert>
<x-slot:title>
{{ $component->formatAlert('Server Error') }}
</x-slot>
 
<strong>Whoops!</strong> Something went wrong!
</x-alert>

插槽屬性

與 Blade 組件一樣,您可以將其他屬性分配給插槽,例如 CSS 類別名稱:

<x-card class="shadow-sm">
<x-slot:heading class="font-bold">
Heading
</x-slot>
 
Content
 
<x-slot:footer class="text-sm">
Footer
</x-slot>
</x-card>

若要與插槽屬性互動,您可以存取插槽變數的 attributes 屬性。如需更多關於如何與屬性互動的資訊,請參閱有關組件屬性的文件:

@props([
'heading',
'footer',
])
 
<div {{ $attributes->class(['border']) }}>
<h1 {{ $heading->attributes->class(['text-lg']) }}>
{{ $heading }}
</h1>
 
{{ $slot }}
 
<footer {{ $footer->attributes->class(['text-gray-700']) }}>
{{ $footer }}
</footer>
</div>

內嵌組件視圖

對於非常小的組件,管理組件類別和組件的視圖範本可能會讓人覺得很麻煩。因此,您可以直接從 render 方法返回組件的標記:

/**
* Get the view / contents that represent the component.
*/
public function render(): string
{
return <<<'blade'
<div class="alert alert-danger">
{{ $slot }}
</div>
blade;
}

產生內聯視圖組件

若要建立渲染內聯視圖的組件,您可以在執行 make:component 指令時使用 inline 選項:

php artisan make:component Alert --inline

動態組件

有時,您可能需要渲染一個組件,但在執行時間之前不知道應該渲染哪個組件。在這種情況下,您可以使用 Laravel 內建的 dynamic-component 組件來根據執行時間值或變數渲染組件:

// $componentName = "secondary-button";
 
<x-dynamic-component :component="$componentName" class="mt-4" />

手動註冊組件

exclamation - Laravel 框架

以下關於手動註冊組件的文件主要適用於正在編寫包含視圖組件的 Laravel 套件的開發人員。如果您不是在編寫套件,則組件文件的此部分可能與您無關。

當為您自己的應用程式撰寫元件時,元件會自動在 app/View/Components 目錄和 resources/views/components 目錄中探索到。

但是,如果您正在建置使用 Blade 組件的套件或將組件放置在非常規目錄中,則您需要手動註冊您的組件類別及其 HTML 標籤別名,以便 Laravel 知道在哪裡找到組件。您通常應該在套件服務提供者的 boot 方法中註冊您的組件:

use Illuminate\Support\Facades\Blade;
use VendorPackage\View\Components\AlertComponent;
 
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::component('package-alert', AlertComponent::class);
}

一旦您的元件已註冊,就可以使用其標籤別名進行渲染。

<x-package-alert/>

自動載入套件組件

或者,您可以使用 componentNamespace 方法來依照慣例自動載入元件類別。例如,Nightshade 套件可能會有 CalendarColorPicker 元件,它們位於 Package\Views\Components 命名空間中。

use Illuminate\Support\Facades\Blade;
 
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

這將允許使用 package-name:: 語法,透過其供應商命名空間使用套件元件。

<x-nightshade::calendar />
<x-nightshade::color-picker />

Blade 將透過將元件名稱轉換為 Pascal 大小寫來自動偵測與此元件連結的類別。子目錄也支援使用「點」表示法。

匿名組件

與內聯組件類似,匿名組件提供了一種透過單一檔案管理組件的機制。但是,匿名組件使用單一視圖檔案,並且沒有相關聯的類別。若要定義匿名組件,您只需要將 Blade 範本放置在您的 resources/views/components 目錄中。例如,假設您已在 resources/views/components/alert.blade.php 中定義了一個組件,您可以像這樣簡單地渲染它:

<x-alert/>

您可以使用 . 字元來指示組件是否更深地巢狀在 components 目錄內。例如,假設組件定義在 resources/views/components/inputs/button.blade.php 中,您可以像這樣渲染它:

<x-inputs.button/>

匿名索引組件

有時,當組件由許多 Blade 範本組成時,您可能希望將給定組件的範本群組在單一目錄中。例如,假設一個「手風琴」組件具有以下目錄結構:

/resources/views/components/accordion.blade.php
/resources/views/components/accordion/item.blade.php

此目錄結構允許您像這樣渲染手風琴組件及其項目:

<x-accordion>
<x-accordion.item>
...
</x-accordion.item>
</x-accordion>

但是,為了透過 x-accordion 渲染手風琴組件,我們被迫將「索引」手風琴組件範本放置在 resources/views/components 目錄中,而不是將其與其他手風琴相關範本巢狀在 accordion 目錄中。

幸好,Blade 允許您在元件的目錄內放置一個與元件目錄名稱相符的檔案。當這個模板存在時,即使它嵌套在目錄中,也可以將其呈現為元件的「根」元素。因此,我們可以繼續使用上面範例中給出的相同 Blade 語法;但是,我們會調整我們的目錄結構如下

/resources/views/components/accordion/accordion.blade.php
/resources/views/components/accordion/item.blade.php

資料屬性 / 屬性

由於匿名元件沒有任何相關的類別,您可能會想知道如何區分哪些資料應該作為變數傳遞給元件,以及哪些屬性應該放置在元件的屬性包中。

您可以使用元件 Blade 模板頂部的 @props 指令來指定哪些屬性應被視為資料變數。元件上的所有其他屬性將透過元件的屬性包提供。如果您想為資料變數提供預設值,您可以將變數的名稱指定為陣列的鍵,並將預設值指定為陣列的值。

<!-- /resources/views/components/alert.blade.php -->
 
@props(['type' => 'info', 'message'])
 
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>

給定上面的元件定義,我們可以這樣呈現元件

<x-alert type="error" :message="$message" class="mb-4"/>

存取父資料

有時您可能想要從父元件內部存取子元件的資料。在這些情況下,您可以使用 @aware 指令。例如,假設我們正在建構一個複雜的選單元件,包含一個父元件 <x-menu> 和子元件 <x-menu.item>

<x-menu color="purple">
<x-menu.item>...</x-menu.item>
<x-menu.item>...</x-menu.item>
</x-menu>

<x-menu> 元件可能具有如下的實作方式

<!-- /resources/views/components/menu/index.blade.php -->
 
@props(['color' => 'gray'])
 
<ul {{ $attributes->merge(['class' => 'bg-'.$color.'-200']) }}>
{{ $slot }}
</ul>

由於 color 屬性僅傳遞給父元件(<x-menu>),它在 <x-menu.item> 內部不可用。但是,如果我們使用 @aware 指令,我們也可以使其在 <x-menu.item> 內部可用

<!-- /resources/views/components/menu/item.blade.php -->
 
@aware(['color' => 'gray'])
 
<li {{ $attributes->merge(['class' => 'text-'.$color.'-800']) }}>
{{ $slot }}
</li>
exclamation - Laravel 框架

@aware 指令無法存取未透過 HTML 屬性明確傳遞給父元件的父資料。未明確傳遞給父元件的預設 @props 值無法被 @aware 指令存取。

匿名元件路徑

如先前討論的,匿名元件通常透過將 Blade 模板放置在 resources/views/components 目錄中來定義。但是,您有時可能想要除了預設路徑之外,向 Laravel 註冊其他匿名元件路徑。

anonymousComponentPath 方法接受匿名元件位置的「路徑」作為其第一個引數,並接受元件應該放置在其下的可選「命名空間」作為其第二個引數。通常,此方法應該從應用程式的其中一個服務提供者boot 方法中呼叫

/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::anonymousComponentPath(__DIR__.'/../components');
}

當元件路徑在沒有指定前綴的情況下註冊(如上面的範例所示),它們也可以在您的 Blade 元件中呈現,而無需對應的前綴。例如,如果 panel.blade.php 元件存在於上面註冊的路徑中,則可以這樣呈現

<x-panel />

可以將前綴「命名空間」作為第二個引數提供給 anonymousComponentPath 方法

Blade::anonymousComponentPath(__DIR__.'/../components', 'dashboard');

當提供前綴時,該「命名空間」內的元件可以透過在呈現元件時將元件的命名空間加上前綴來呈現

<x-dashboard::panel />

建立版面配置

使用組件的版面配置

大多數 Web 應用程式在各種頁面上都保持相同的通用佈局。如果我們必須在我們建立的每個視圖中重複整個佈局 HTML,那將會非常麻煩且難以維護我們的應用程式。幸好,將此佈局定義為單一的 Blade 元件,然後在整個應用程式中使用它很方便。

定義佈局元件

例如,假設我們正在建構一個「待辦事項」清單應用程式。我們可能會定義一個如下所示的 layout 元件

<!-- resources/views/components/layout.blade.php -->
 
<html>
<head>
<title>{{ $title ?? 'Todo Manager' }}</title>
</head>
<body>
<h1>Todos</h1>
<hr/>
{{ $slot }}
</body>
</html>

應用佈局元件

一旦定義了 layout 元件,我們可以建立一個使用該元件的 Blade 視圖。在這個範例中,我們將定義一個簡單的視圖來顯示我們的任務清單

<!-- resources/views/tasks.blade.php -->
 
<x-layout>
@foreach ($tasks as $task)
<div>{{ $task }}</div>
@endforeach
</x-layout>

請記住,注入到元件中的內容將提供給 layout 元件內的預設 $slot 變數。正如您可能已經注意到的,如果提供了 $title 插槽,我們的 layout 也會遵循;否則,會顯示預設標題。我們可以從我們的任務清單視圖中使用 元件文件中討論的標準插槽語法來注入自訂標題

<!-- resources/views/tasks.blade.php -->
 
<x-layout>
<x-slot:title>
Custom Title
</x-slot>
 
@foreach ($tasks as $task)
<div>{{ $task }}</div>
@endforeach
</x-layout>

現在我們已經定義了我們的佈局和任務清單視圖,我們只需要從路由返回 task 視圖

use App\Models\Task;
 
Route::get('/tasks', function () {
return view('tasks', ['tasks' => Task::all()]);
});

使用樣板繼承的版面配置

定義佈局

佈局也可以透過「模板繼承」來建立。這是引入 元件 之前建立應用程式的主要方法。

首先,讓我們看一個簡單的範例。首先,我們將檢查頁面佈局。由於大多數 Web 應用程式在各種頁面上都保持相同的通用佈局,因此將此佈局定義為單一的 Blade 視圖很方便

<!-- resources/views/layouts/app.blade.php -->
 
<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
 
<div class="container">
@yield('content')
</div>
</body>
</html>

如您所見,此檔案包含典型的 HTML 標記。但是,請注意 @section@yield 指令。顧名思義,@section 指令定義內容的區塊,而 @yield 指令用於顯示給定區塊的內容。

現在我們已經定義了應用程式的佈局,讓我們定義一個繼承該佈局的子頁面。

擴充佈局

當定義子視圖時,使用 @extends Blade 指令來指定子視圖應該「繼承」哪個佈局。擴充 Blade 佈局的視圖可以使用 @section 指令將內容注入到佈局的區塊中。請記住,如上面的範例所示,這些區塊的內容將使用 @yield 顯示在佈局中。

<!-- resources/views/child.blade.php -->
 
@extends('layouts.app')
 
@section('title', 'Page Title')
 
@section('sidebar')
@parent
 
<p>This is appended to the master sidebar.</p>
@endsection
 
@section('content')
<p>This is my body content.</p>
@endsection

在這個範例中,sidebar 區塊使用 @parent 指令來附加(而不是覆寫)內容到佈局的側邊欄。當視圖呈現時,@parent 指令將被佈局的內容取代。

lightbulb - Laravel 框架

與之前的範例相反,這個 sidebar 區塊以 @endsection 而不是 @show 結尾。@endsection 指令只會定義一個區塊,而 @show 將會定義並立即輸出該區塊。

@yield 指令也接受預設值作為其第二個參數。如果未定義要輸出的區塊,則會呈現此值

@yield('content', 'Default content')

表單

CSRF 欄位

每當您在應用程式中定義 HTML 表單時,您應該在表單中包含一個隱藏的 CSRF 權杖欄位,以便CSRF 保護中介軟體可以驗證請求。您可以使用 @csrf Blade 指令來產生權杖欄位

<form method="POST" action="/profile">
@csrf
 
...
</form>

方法欄位

由於 HTML 表單無法發出 PUTPATCHDELETE 請求,您需要新增一個隱藏的 _method 欄位來模擬這些 HTTP 動詞。@method Blade 指令可以為您建立此欄位

<form action="/foo/bar" method="POST">
@method('PUT')
 
...
</form>

驗證錯誤

@error 指令可用於快速檢查給定屬性是否存在驗證錯誤訊息。在 @error 指令內,您可以輸出 $message 變數來顯示錯誤訊息

<!-- /resources/views/post/create.blade.php -->
 
<label for="title">Post Title</label>
 
<input
id="title"
type="text"
class="@error('title') is-invalid @enderror"
/>
 
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror

由於 @error 指令會編譯成「if」陳述式,您可以使用 @else 指令在屬性沒有錯誤時呈現內容

<!-- /resources/views/auth.blade.php -->
 
<label for="email">Email address</label>
 
<input
id="email"
type="email"
class="@error('email') is-invalid @else is-valid @enderror"
/>

您可以將特定錯誤包的名稱作為第二個參數傳遞給 @error 指令,以在包含多個表單的頁面上檢索驗證錯誤訊息

<!-- /resources/views/auth.blade.php -->
 
<label for="email">Email address</label>
 
<input
id="email"
type="email"
class="@error('email', 'login') is-invalid @enderror"
/>
 
@error('email', 'login')
<div class="alert alert-danger">{{ $message }}</div>
@enderror

堆疊

Blade 允許您推送到命名的堆疊,這些堆疊可以在另一個視圖或佈局中的其他位置呈現。這對於指定子視圖所需的任何 JavaScript 程式庫特別有用

@push('scripts')
<script src="/example.js"></script>
@endpush

如果您想在給定的布林運算式評估為 true@push 內容,您可以使用 @pushIf 指令

@pushIf($shouldPush, 'scripts')
<script src="/example.js"></script>
@endPushIf

您可以根據需要多次推送到堆疊。要呈現完整的堆疊內容,請將堆疊的名稱傳遞給 @stack 指令

<head>
<!-- Head Contents -->
 
@stack('scripts')
</head>

如果您想將內容添加到堆疊的開頭,您應該使用 @prepend 指令

@push('scripts')
This will be second...
@endpush
 
// Later...
 
@prepend('scripts')
This will be first...
@endprepend

服務注入

@inject 指令可用於從 Laravel 服務容器檢索服務。傳遞給 @inject 的第一個引數是服務將放入的變數名稱,而第二個引數是您想要解析的服務的類別或介面名稱

@inject('metrics', 'App\Services\MetricsService')
 
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>

渲染內嵌 Blade 樣板

有時您可能需要將原始 Blade 模板字串轉換為有效的 HTML。您可以使用 Blade 外觀提供的 render 方法來完成此操作。render 方法接受 Blade 模板字串和可選的資料陣列以提供給模板

use Illuminate\Support\Facades\Blade;
 
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);

Laravel 通過將內聯 Blade 模板寫入 storage/framework/views 目錄來呈現它們。如果您希望 Laravel 在呈現 Blade 模板後移除這些臨時檔案,您可以將 deleteCachedView 引數提供給方法

return Blade::render(
'Hello, {{ $name }}',
['name' => 'Julian Bashir'],
deleteCachedView: true
);

渲染 Blade 片段

當使用前端框架(例如 Turbohtmx)時,您有時可能只需要在 HTTP 回應中返回 Blade 模板的一部分。Blade 「片段」允許您做到這一點。首先,將 Blade 模板的一部分放置在 @fragment@endfragment 指令之間

@fragment('user-list')
<ul>
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
</ul>
@endfragment

然後,當呈現使用此模板的視圖時,您可以呼叫 fragment 方法來指定只有指定的片段應該包含在傳出的 HTTP 回應中

return view('dashboard', ['users' => $users])->fragment('user-list');

fragmentIf 方法允許您根據給定的條件有條件地返回視圖的片段。否則,將返回整個視圖

return view('dashboard', ['users' => $users])
->fragmentIf($request->hasHeader('HX-Request'), 'user-list');

fragmentsfragmentsIf 方法允許您在回應中返回多個視圖片段。這些片段將會串連在一起

view('dashboard', ['users' => $users])
->fragments(['user-list', 'comment-list']);
 
view('dashboard', ['users' => $users])
->fragmentsIf(
$request->hasHeader('HX-Request'),
['user-list', 'comment-list']
);

擴展 Blade

Blade 允許您使用 directive 方法定義自己的自訂指令。當 Blade 編譯器遇到自訂指令時,它將使用該指令包含的運算式呼叫提供的回呼。

以下範例建立一個 @datetime($var) 指令,它會格式化給定的 $var,該 $var 應該是 DateTime 的實例

<?php
 
namespace App\Providers;
 
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::directive('datetime', function (string $expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
}

如您所見,我們將把 format 方法鏈接到傳遞給指令的任何運算式。因此,在此範例中,此指令產生的最終 PHP 將會是

<?php echo ($var)->format('m/d/Y H:i'); ?>
exclamation - Laravel 框架

在更新 Blade 指令的邏輯後,您將需要刪除所有快取的 Blade 視圖。可以使用 view:clear Artisan 命令移除快取的 Blade 視圖。

自訂 Echo 處理器

如果您嘗試使用 Blade「echo」一個物件,將會調用該物件的 __toString 方法。__toString 方法是 PHP 內建的「魔術方法」之一。然而,有時候您可能無法控制特定類別的 __toString 方法,例如當您互動的類別屬於第三方函式庫時。

在這些情況下,Blade 允許您為特定類型的物件註冊自訂的 echo 處理器。為了達成此目的,您應該調用 Blade 的 stringable 方法。stringable 方法接受一個閉包。此閉包應該類型提示它負責渲染的物件類型。通常,stringable 方法應該在您應用程式的 AppServiceProvider 類別的 boot 方法中調用。

use Illuminate\Support\Facades\Blade;
use Money\Money;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::stringable(function (Money $money) {
return $money->formatTo('en_GB');
});
}

一旦您的自訂 echo 處理器被定義,您就可以直接在您的 Blade 模板中 echo 該物件。

Cost: {{ $money }}

自訂 If 語句

當定義簡單的自訂條件陳述式時,編寫自訂指令有時可能過於複雜。因此,Blade 提供了一個 Blade::if 方法,允許您使用閉包快速定義自訂條件指令。例如,讓我們定義一個自訂條件,檢查應用程式設定的預設「磁碟」。我們可以在 AppServiceProviderboot 方法中完成此操作。

use Illuminate\Support\Facades\Blade;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::if('disk', function (string $value) {
return config('filesystems.default') === $value;
});
}

一旦自訂條件被定義,您就可以在您的模板中使用它。

@disk('local')
<!-- The application is using the local disk... -->
@elsedisk('s3')
<!-- The application is using the s3 disk... -->
@else
<!-- The application is using some other disk... -->
@enddisk
 
@unlessdisk('local')
<!-- The application is not using the local disk... -->
@enddisk