拒絕 View 層義大利麵!Laravel 11 Blade 模板現代化架構與 Component 實戰指南

2026/01/7 | Laravel技術分享, 全端與程式開發

告別 View 層義大利麵:Laravel Blade 現代化架構與 Component 實戰

您的 View 層是否也充滿了難以維護的「義大利麵程式碼」?資深工程師 Eric 帶您深入解析 Laravel Blade 的三大病灶,並指出邏輯外洩是維護性低落的主因。本指南強調擁抱現代化的 Blade Component(<x-component>)以取代傳統的 @include,並教您如何將複雜邏輯移出 View 層,徹底實踐純淨架構。立即學習 Laravel 11 的 @use@class 等新指令,將您的專案從技術債深淵中拯救出來!從今天開始重構,大幅提升程式碼可讀性與開發效率!

需要專業協助?

聯絡浪花專案團隊 →

拒絕 View 層義大利麵!Laravel 11 Blade 模板現代化架構與 Component 實戰指南

嗨,我是 Eric,浪花科技的資深工程師。今天我要來聊聊一個讓許多 Laravel 開發者(尤其是剛從這坑跳進來的)又愛又恨的主題:Blade 模板

上週我在幫一位新進工程師 Code Review 時,打開了一個 index.blade.php,當場差點心肌梗塞。為什麼?因為我在這份「View」檔案裡看到了複雜的資料庫查詢、未經處理的 PHP 原生陣列操作,還有巢狀了五層的 if-else 判斷式。這不是 View,這是義大利麵(Spaghetti Code),而且是放了三天糊成一團的那種。

很多人認為 Blade 只是拿來「顯示 HTML」的,所以隨便寫沒關係。錯!大錯特錯!一個維護性高的 Laravel 專案,View 層的架構整潔度,絕對不亞於後端的 Service 或 Repository。隨著 Laravel 11 的發布,Blade 已經演化成一個強大的元件化(Component-based)系統。

今天這篇文章,我要把多年的血淚經驗濃縮成這篇「Laravel Blade 模板最佳實務」,教你如何寫出優雅、可維護,且符合現代化開發標準的 View。

為什麼你的 Blade 總是亂七八糟?常見的三大病灶

在進入技術細節前,我們先來診斷一下,你的 Blade 是否患了以下幾種常見疾病:

  • 邏輯外洩 (Logic Leaking): 在 Blade 裡面寫 Eloquent Query (User::where(...)->get())。這是大忌!View 應該只負責「呈現」,不負責「思考」。
  • 過度依賴 @include: 雖然 @include 很好用,但它無法很好地處理資料作用域(Scope)和屬性傳遞,導致子視圖變得難以預測。
  • 複製貼上魔人: 按鈕、表單輸入框、卡片樣式在每個檔案都重寫一遍,只要設計師一改 UI,全公司工程師都要加班改 Code。

1. 擁抱 Component (元件),拋棄 @include

如果你還在大量使用 @include('partials.header'),現在是時候改變習慣了。從 Laravel 7 開始引入的 Blade Components (x-components) 才是現代化的標準寫法。

為什麼 Component 比較好?

Component 允許你像寫 HTML 標籤一樣使用你的元件,並且提供了強大的屬性包(Attribute Bag)功能,這讓你的程式碼語意更清晰。

傳統 @include 寫法(容易混亂):


{{-- 參數傳遞不明確,無法強制型別 --}}
@include('components.button', ['type' => 'primary', 'text' => '送出表單'])

現代 Component 寫法(語意清晰):


<!-- 看起來就像原生 HTML,支援 Slot 和預設屬性合併 -->
<x-button type="primary" class="mt-4">
    送出表單
</x-button>

實戰:建立一個可複用的 Alert 元件

我們可以使用 Artisan 指令快速建立元件:

php artisan make:component Alert --view

接著在 resources/views/components/alert.blade.php 中:


@props(['type' => 'info']) 

@php
    $colors = [
        'info' => 'bg-blue-100 text-blue-800',
        'error' => 'bg-red-100 text-red-800',
        'success' => 'bg-green-100 text-green-800',
    ];
    $classes = $colors[$type] ?? $colors['info'];
@endphp

<div {{ $attributes->merge(['class' => "p-4 rounded-lg $classes"]) }}>
    {{ $slot }}
</div>

Eric 的囉嗦重點: 注意那個 $attributes->merge()。這是 Component 最強大的功能之一,它允許你在呼叫元件時傳入額外的 CSS class(例如 mb-4),並自動與元件預設的 class 合併。如果你用 @include,這功能你得自己手刻到天荒地老。

2. 保持 View 層純淨:Logic 應該在哪裡?

這是我最常強調的一點:View 不應該包含複雜的商業邏輯。

如果你發現自己在 Blade 裡寫了大量的 @php 區塊來處理資料轉換,請停下來。你有幾個更好的選擇:

選項 A:Accessor (存取器) 與 Presenter

如果是簡單的資料格式化(例如日期、金額),請在 Model 使用 Accessor,或者使用 Laravel 的 API Resource / Presenter 模式。

選項 B:View Models (視圖模型)

當頁面邏輯非常複雜時(例如儀表板),Controller 傳給 View 的變數會變得雜亂無章。這時可以考慮 View Model 模式。這不是 Laravel 內建的,但這是一個非常棒的 Design Pattern。


// 糟糕的寫法:在 Blade 裡面算數學
Total: {{ $order->items->sum(fn($item) => $item->price * $item->quantity) * 1.05 }}

// 優雅的寫法:Model 或 Presenter 處理好
Total: {{ $order->total_with_tax }}

3. Laravel 11 新特性:更簡潔的 Blade

隨著 Laravel 10 和 11 的推進,Blade 也變得更聰明了。有一個經常被忽略但極好用的 Directive:@use

以前如果你要在 Blade 裡使用某些 Enum 或 Class 常數,你可能需要傳入 View,或者寫完整的 Namespace:


{{-- 舊寫法 --}}
@if($user->status === \App\Enums\UserStatus::ACTIVE)
    <span>啟用中</span>
@endif

現在,你可以直接使用 @use,讓程式碼更乾淨:


{{-- Laravel 10/11 新寫法 --}}
@use('App\Enums\UserStatus')

@if($user->status === UserStatus::ACTIVE)
    <span>啟用中</span>
@endif

4. 效能優化:別在迴圈裡埋地雷

Blade 的效能問題通常源自於資料庫查詢的 N+1 問題。雖然這主要是在 Controller 層解決(使用 Eager Loading with()),但在 Blade 層也有防守的方式。

避免在 Blade 呼叫關聯關係:

千萬不要在 @foreach 迴圈中呼叫類似 $user->posts()->count() 的方法。因為 () 會觸發新的 SQL Query。如果一定要用,請確保你在 Controller 已經用 withCount('posts') 載入過了。

善用 @class 與 @style:

這不是效能優化,而是開發效率優化。不要再寫醜陋的三元運算子來決定 CSS Class 了。


{{-- 舊寫法:難以閱讀 --}}
<div class="p-4 {{ $isActive ? 'bg-blue-500' : 'bg-gray-200' }}">...</div>

{{-- 新寫法:條件式 Class --}}
<div @class([
    'p-4',
    'bg-blue-500' => $isActive,
    'bg-gray-200' => ! $isActive,
])>
    ...
</div>

5. Eric 的 Blade Code Review 檢查清單

最後,身為資深工程師,我幫大家整理了一份檢查清單。下次 Commit 程式碼前,請先自我檢查:

  • [ ] 是否使用了 <x-component> 而不是 @include
  • [ ] Blade 檔案中是否沒有任何 Model::query() 資料庫查詢?
  • [ ] 是否移除了複雜的 PHP 邏輯運算,改由 Controller 或 Accessor 提供?
  • [ ] 是否使用了 @forelse 來優化空資料的顯示,而不是 @if($items->count() > 0) ... @foreach
  • [ ] 巢狀迴圈是否超過 3 層?如果是,請考慮拆分成子元件 (Sub-components)。
  • [ ] 你的 Layout 是否使用了 Component Layout (<x-app-layout>) 而不是舊式的 @extends?(這也是現代 Laravel 的推薦做法)

結論:好的 Blade 讓你下班早回家

Blade 模板不僅僅是 HTML 的容器,它是你應用程式呈現層的靈魂。透過 Component 架構、邏輯分離以及善用 Laravel 11 的新語法,你的 View 層將不再是難以維護的義大利麵,而是結構嚴謹的積木城堡。

技術債這種東西,是會有複利的。今天偷懶寫在 View 裡的邏輯,下個月就會變成你加班的理由。從今天開始,善待你的 Blade 吧!

如果你在 Laravel 架構設計上遇到瓶頸,或是想要針對既有的專案進行效能健檢與重構,歡迎隨時聯繫我們。

立即預約 Laravel 架構諮詢

延伸閱讀

常見問題 (FAQ)

Q1: 已經有很多舊的 @include 程式碼,需要全部重構成 Component 嗎?

不必急著一次全部重構。Eric 建議採用「童子軍法則」:當你需要修改某個舊檔案,或者開發新功能時,再順手將相關的部份重構為 Component。漸進式改進比大規模重寫風險更低。

Q2: Blade 跟 Vue.js / React 該怎麼選擇?

如果你的應用程式互動性不高(主要是展示資訊、簡單表單),Blade + Alpine.js 是開發速度最快且 SEO 最好的組合。如果你需要高度互動的 SPA(單頁應用)體驗,或者複雜的狀態管理,那麼 Laravel + Vue/React (透過 Inertia.js 或 API) 會是更好的選擇。

Q3: 在 Blade 裡面使用 @php … @endphp 真的很糟嗎?

少量的變數賦值是可以接受的(例如設定 Component 的 class 樣式)。但如果是進行資料庫查詢、API 呼叫或複雜的陣列處理,絕對是 Bad Practice。這些邏輯應該在 Controller、Service 或 View Model 中完成。

 
立即諮詢,索取免費1年網站保固