View

簡介

當那果然,直接從 Route 或 Controller 中回傳整個 HTML 文件字串不是很實際。幸好,使用 View,我們就能方便地將所有的 HTML 都放在獨立的檔案中。

使用 View 就可從 Controller / 應用程式的邏輯中將顯示邏輯拆出來並放在 resources/views 目錄下。使用 Laravel 時,View 樣板通常使用 Blade 樣板語言撰寫。一個簡單的 View 看起來可能像這樣:

1<!-- View 保存於 resources/views/greeting.blade.php -->
2 
3<html>
4 <body>
5 <h1>Hello, {{ $name }}</h1>
6 </body>
7</html>
1<!-- View 保存於 resources/views/greeting.blade.php -->
2 
3<html>
4 <body>
5 <h1>Hello, {{ $name }}</h1>
6 </body>
7</html>

這個 View 保存在 resources/views/greeting.blade.php,因此我們可以像這樣使用全域的 view 輔助函式來回傳 View:

1Route::get('/', function () {
2 return view('greeting', ['name' => 'James']);
3});
1Route::get('/', function () {
2 return view('greeting', ['name' => 'James']);
3});
lightbulb

想瞭解更多有關如何撰寫 Blade 樣板的資訊嗎?請參考完整的 Blade 說明文件來入門 Blade 樣板。

以 React 或 Vue 來撰寫 View

除了使用 Blade 來在 PHP 中撰寫前端樣板外,許多開發人員也開始偏好使用 React 或 Vue 來撰寫樣板。在 Laravel 中,多虧有了 Inertia,要使用 React 或 Vue 來撰寫樣板一點也不麻煩。Inertia 是一個可將 React 或 Vue 前端與 Laravel 後端搭配使用的一個套件,可讓我們不需處理建立 SPA 常見的麻煩。

Laravel 的 Breeze 與 Jetstream 入門套件 藉由 Inertia 驅動,能讓你在製作下一個 Laravel 專案時有個好的起始點。此外,Laravel Bootcamp 還提供了使用 Inertia 製作 Laravel 專案的完整示範,並包含了使用 Vue 與 React 的範例。

建立與轉譯 View

我們可以在專案的 resources/views 目錄下放置一個副檔名為 .blade.php 的檔案來建立 View。.blade.php 副檔名告訴 Laravel 這個檔案時一個 Blade 樣板。Blade 樣板中包含 HTML 與 Blade 指示詞 (Directive),Blade 指示詞可用來輕鬆地輸出 (Echo) 資料、建立「if」陳述式、迭代資料⋯⋯等。

建立好 View 之後,就可以在專案的 Route 或 Controller 中使用全域的 view 輔助函式來回傳 View:

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

也可以使用 View Facade 來回傳 View

1use Illuminate\Support\Facades\View;
2 
3return View::make('greeting', ['name' => 'James']);
1use Illuminate\Support\Facades\View;
2 
3return View::make('greeting', ['name' => 'James']);

就像我們可以看到的,傳給 view 輔助函式的第一個引數是 View 檔案在 resources/view 目錄下對應的名稱。第二個引數是一組資料陣列,包含要提供給 View 的資料。在這個情況下,我們傳入了一個 name 變數,並在 View 裡面使用 Blade 語法來顯示。

巢狀的 View 目錄

View 也可以巢狀放置在 resources/views 目錄中的子目錄。可使用「點 (.)」標記法來參照巢狀的 View。舉例來說,若有個 View 保存在 resources/views/admin/profile.blade.php,則我們可以在我們程式的 Route 或 Controller 中像這樣回傳這個 View:

1return view('admin.profile', $data);
1return view('admin.profile', $data);
exclamation

View 目錄的名稱不可包含 . 字元。

建立第一個可用的 View

使用 View Facade 的 first 方法,就可以建立給定 View 陣列中存在的第一個 View。這個方法適用於你的專案或套件能自訂 View 或複寫 View 時:

1use Illuminate\Support\Facades\View;
2 
3return View::first(['custom.admin', 'admin'], $data);
1use Illuminate\Support\Facades\View;
2 
3return View::first(['custom.admin', 'admin'], $data);

判斷某個 View 是否存在

若有需要判斷某個 View 是否存在,可使用 View Facade。exists 方法會在 View 存在時回傳 true

1use Illuminate\Support\Facades\View;
2 
3if (View::exists('emails.customer')) {
4 // ...
5}
1use Illuminate\Support\Facades\View;
2 
3if (View::exists('emails.customer')) {
4 // ...
5}

將資料傳給 View

就像我們在前一個範例中看到的一樣,我們可以傳入一組資料陣列給 View 來讓這些資料在 View 中可用:

1return view('greetings', ['name' => 'Victoria']);
1return view('greetings', ['name' => 'Victoria']);

用這種方式傳遞資料時,這些專遞的資料應該是有索引鍵 / 值配對的陣列。將資料提供給 View 後,就可以使用這些資料的索引鍵來在 View 中存取其值,如 <?php echo $name; ?>

除了將完整的資料陣列傳給 view 輔助函式外,也可以使用 with 方法來將單一資料項目提供給 View。with 方法會回傳 View 物件的實體,這樣一來我們就能在回傳 View 前繼續串上其他方法呼叫:

1return view('greeting')
2 ->with('name', 'Victoria')
3 ->with('occupation', 'Astronaut');
1return view('greeting')
2 ->with('name', 'Victoria')
3 ->with('occupation', 'Astronaut');

在所有 View 間共用資料

有時候,我們會需要在所有的 View 間共享某個資料。為此,可以使用 View Facade 的 share 方法。一般來說,我們應該在某個 Service Provider 的 boot 方法中呼叫 share 方法。我們可以在 App\Providers\AppServiceProvider 類別中呼叫,或者也可以建立一個獨立的 Service Provider 來放置共享的資料:

1<?php
2 
3namespace App\Providers;
4 
5use Illuminate\Support\Facades\View;
6 
7class AppServiceProvider extends ServiceProvider
8{
9 /**
10 * Register any application services.
11 */
12 public function register(): void
13 {
14 // ...
15 }
16 
17 /**
18 * Bootstrap any application services.
19 */
20 public function boot(): void
21 {
22 View::share('key', 'value');
23 }
24}
1<?php
2 
3namespace App\Providers;
4 
5use Illuminate\Support\Facades\View;
6 
7class AppServiceProvider extends ServiceProvider
8{
9 /**
10 * Register any application services.
11 */
12 public function register(): void
13 {
14 // ...
15 }
16 
17 /**
18 * Bootstrap any application services.
19 */
20 public function boot(): void
21 {
22 View::share('key', 'value');
23 }
24}

View Composer

View Composer 是 View 在轉譯時會呼叫的回呼或類別方法。若你有一筆想在每次轉譯 View 時要繫結到 View 上的資料時,可以使用 View Composer 來協助我們將這類的邏輯拆分到一個地方。當你的程式中有許多的 Route 或 Controller 都回傳相同的 View,且這些 View 都需要同樣的資料時,View Composer 就特別適合。

一般來說,我們可以在專案的某個 Service Providers 中註冊 View Composer。在這個例子中,先假設我們建立了一個新的 App\Providers\ViewServiceProvider 來放置這個邏輯:

我們會使用 View Facade 的 composer 方法來註冊 View Composer。Laravel 並沒有提供放置基於類別的 View Composer 用的預設目錄,因此我們可以隨意放置 View Composer。舉例來說,我們可以建立一個 app/View/Composers 目錄來放置所有的 View Composer:

1<?php
2 
3namespace App\Providers;
4 
5use App\View\Composers\ProfileComposer;
6use Illuminate\Support\Facades;
7use Illuminate\Support\ServiceProvider;
8use Illuminate\View\View;
9 
10class ViewServiceProvider extends ServiceProvider
11{
12 /**
13 * Register any application services.
14 */
15 public function register(): void
16 {
17 // ...
18 }
19 
20 /**
21 * Bootstrap any application services.
22 */
23 public function boot(): void
24 {
25 // 使用基於類別的 Composer...
26 Facades\View::composer('profile', ProfileComposer::class);
27 
28 // 使用基於閉包的 Composer...
29 Facades\View::composer('welcome', function (View $view) {
30 // ...
31 });
32 
33 Facades\View::composer('dashboard', function (View $view) {
34 // ...
35 });
36 }
37}
1<?php
2 
3namespace App\Providers;
4 
5use App\View\Composers\ProfileComposer;
6use Illuminate\Support\Facades;
7use Illuminate\Support\ServiceProvider;
8use Illuminate\View\View;
9 
10class ViewServiceProvider extends ServiceProvider
11{
12 /**
13 * Register any application services.
14 */
15 public function register(): void
16 {
17 // ...
18 }
19 
20 /**
21 * Bootstrap any application services.
22 */
23 public function boot(): void
24 {
25 // 使用基於類別的 Composer...
26 Facades\View::composer('profile', ProfileComposer::class);
27 
28 // 使用基於閉包的 Composer...
29 Facades\View::composer('welcome', function (View $view) {
30 // ...
31 });
32 
33 Facades\View::composer('dashboard', function (View $view) {
34 // ...
35 });
36 }
37}
exclamation

請記得,若要建立一個新的 Service Provider 來放置 View ‘Composer 的註冊,就需要將這個新建立的 Service Provider 新增到 config/app.php 設定檔的 providers 陣列。

現在,我們已經註冊好 Composer 了。每當轉譯 profile View 時,就會執行 App\View\Composers\ProfileComposer 類別的 compose 方法。我慢來看看這個 Composer 類別的例子:

1<?php
2 
3namespace App\View\Composers;
4 
5use App\Repositories\UserRepository;
6use Illuminate\View\View;
7 
8class ProfileComposer
9{
10 /**
11 * Create a new profile composer.
12 */
13 public function __construct(
14 protected UserRepository $users,
15 ) {}
16 
17 /**
18 * Bind data to the view.
19 */
20 public function compose(View $view): void
21 {
22 $view->with('count', $this->users->count());
23 }
24}
1<?php
2 
3namespace App\View\Composers;
4 
5use App\Repositories\UserRepository;
6use Illuminate\View\View;
7 
8class ProfileComposer
9{
10 /**
11 * Create a new profile composer.
12 */
13 public function __construct(
14 protected UserRepository $users,
15 ) {}
16 
17 /**
18 * Bind data to the view.
19 */
20 public function compose(View $view): void
21 {
22 $view->with('count', $this->users->count());
23 }
24}

就像我們可以看到的,所有的 View Composer 都會經過 [Service Container] 解析,因此我們可以在 Composer 的 Constructor (建構函式) 上型別提示 (Type-Hint) 任何需要的相依性。

將 Composer 附加到多個 View 上

只要將一組 View 陣列作為第一個引數傳給 composer 方法,我們就可以一次將一個 View Composer 附加到多個 View 上:

1use App\Views\Composers\MultiComposer;
2use Illuminate\Support\Facades\View;
3 
4View::composer(
5 ['profile', 'dashboard'],
6 MultiComposer::class
7);
1use App\Views\Composers\MultiComposer;
2use Illuminate\Support\Facades\View;
3 
4View::composer(
5 ['profile', 'dashboard'],
6 MultiComposer::class
7);

composer 方法也接受使用 * 字元作為萬用字元。這樣我們就可以將某個 Composer 附加到所有 View 上:

1use Illuminate\Support\Facades;
2use Illuminate\View\View;
3 
4Facades\View::composer('*', function (View $view) {
5 // ...
6});
1use Illuminate\Support\Facades;
2use Illuminate\View\View;
3 
4Facades\View::composer('*', function (View $view) {
5 // ...
6});

View Creator

View "Creator" 與 View Composer 非常類似。不過,View Creator 會在 View 被初始化後馬上執行,而不是在 View 要轉譯前才執行。若要註冊 View Creator,請使用 creator 方法:

1use App\View\Creators\ProfileCreator;
2use Illuminate\Support\Facades\View;
3 
4View::creator('profile', ProfileCreator::class);
1use App\View\Creators\ProfileCreator;
2use Illuminate\Support\Facades\View;
3 
4View::creator('profile', ProfileCreator::class);

最佳化 View

預設情況下,Blade 樣板的 View 會在被使用時候才編譯。當正在執行的 Request 要轉譯 View 時,Laravel 會判斷這個 View 是否有已編譯的版本。若有已編譯版本,則 Laravel 會接著比較未編譯版本的 View 是否比已編譯版本新。若這個 View 沒有已編譯好的版本,或是未編譯版本有修改過,則 Laravel 會重新編譯這個 View。

在 Request 中編譯 View 會對效能造成一點點的負面影響。因此,Laravel 提供了一個 view:cache Artisan 指令,來讓我們預先編譯專案中使用的所有 View。為了提升效能,建議在部署流程中執行這個指令:

1php artisan view:cache
1php artisan view:cache

可以使用 view:clear 指令來清除 View 快取:

1php artisan view:clear
1php artisan view:clear
翻譯進度
100% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
  • cornch
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.