程式碼不是能動就好!資深工程師的 Laravel Blade 模板終極聖經,寫出讓同事愛上你的優雅 Code

2025/08/22 | Laravel技術分享

程式碼不是能動就好!資深工程師的 Laravel Blade 模板終極聖經,寫出讓同事愛上你的優雅 Code

嗨,我是浪花科技的 Eric。身為一個天天在程式碼海裡打滾的工程師,我看過太多令人「驚艷」的 Blade 模板了。你懂的,就是那種把商業邏輯、資料庫查詢、甚至是小型應用程式都塞進一個 `.blade.php` 檔案的奇觀。程式碼能動嗎?或許吧。但它好維護嗎?當需求變更時,你敢碰它嗎?你的同事看得懂嗎?我猜答案是否定的。

寫程式,從來就不只是「讓它動起來」這麼簡單。尤其在團隊協作中,一份乾淨、優雅、可讀性高的程式碼,價值遠超過那些跑得飛快但沒人敢碰的「黑魔法」。今天,我就要以一個資深工程師的囉嗦角度,帶你深入探索 Laravel Blade 模板最佳實務,從基礎佈局到進階效能優化,教你寫出不只會動,更能讓團隊夥伴為你鼓掌的 Blade Code!

地基打穩:佈局(Layouts)與區塊(Sections)的黃金法則

想像一下你在蓋房子,你總不會每間房間都從地基、鋼筋、牆壁開始蓋吧?你會先設計一個共通的藍圖(例如建築結構、水電管線),然後再針對每個房間做客製化裝潢。在 Blade 的世界裡,這個藍圖就是「佈局(Layouts)」。

透過 @extends, @section, 和 @yield 這三兄弟,我們可以輕鬆打造可重複使用的網站骨架。@extends 用來宣告目前的模板要繼承哪一個佈局檔案,@yield 則是在佈局中「挖洞」,等著子模板來填滿,而 @section 就是子模板用來填洞的內容。

這聽起來很基本,但魔鬼藏在細節裡。一個常見的錯誤是濫用 @yield,導致佈局檔充滿了各種用途不明的洞,反而增加了維護的複雜度。

@yield vs. @stack:不只是堆東西這麼簡單

@yield 很好用,但它一次只能被填一個洞。如果我們希望在多個子模板中,都能「追加」內容到同一個區塊呢?例如,每個頁面可能都有自己專屬的 CSS 或 JavaScript 需要放在 <head><body> 結尾。這時候,@stack 就派上用場了。

你可以在佈局檔中使用 @stack('scripts') 來定義一個可以「堆疊」內容的區域,然後在子模板中用 @push('scripts') ... @endpush 來把內容推進去。所有推進來的內容都會被堆疊在一起,非常適合用來管理頁面專屬的資源檔。

看看這個例子:

<!-- resources/views/layouts/app.blade.php -->
<html>
    <head>
        <title>@yield('title', '我的網站')</title>
        @stack('styles')
    </head>
    <body>
        <div class="container">
            @yield('content')
        </div>
        @stack('scripts')
    </body>
</html>

<!-- resources/views/users/index.blade.php -->
@extends('layouts.app')

@section('title', '使用者列表')

@push('styles')
    <link rel="stylesheet" href="/css/users.css">
@endpush

@section('content')
    <h1>這裡是使用者列表</h1>
@endsection

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

你看,這樣是不是既優雅又好管理?佈局檔保持乾淨,每個頁面的依賴也一目了然。

告別複製貼上地獄:擁抱元件化(Component-Driven)開發思維

如果說 Layouts 是房子的藍圖,那 Components(元件)就是標準化的「積木」,例如窗戶、門、磚塊。當你的網站越來越複雜,你會發現很多 UI 元素(按鈕、卡片、表單輸入框、警告訊息)會不斷重複出現。身為一個有格調的工程師,複製貼上絕對是我們要避免的陋習。

Laravel 7 之後引入的匿名組件(Anonymous Components)徹底改變了 Blade 的開發體驗。它讓我們能用類似 Vue 或 React 的語法,輕鬆地建立和使用可重複的 UI 元件。

匿名組件(Anonymous Components):你的新好朋友 <x-component>

匿名組件超級直覺。你只需要在 resources/views/components 資料夾下建立一個 Blade 檔案,就可以在任何地方用 <x-檔名> 的方式呼叫它。資料傳遞透過屬性(Props),而內容嵌入則透過 $slot 變數。

舉個例子,我們來做一個通用的警告訊息元件:

<!-- resources/views/components/alert.blade.php -->
@props(['type' => 'info'])

@php
    $colors = [
        'info' => 'bg-blue-100 border-blue-500 text-blue-700',
        'success' => 'bg-green-100 border-green-500 text-green-700',
        'warning' => 'bg-yellow-100 border-yellow-500 text-yellow-700',
        'danger' => 'bg-red-100 border-red-500 text-red-700',
    ];
@endphp

<div class="{{ $colors[$type] }} border-l-4 p-4" role="alert">
    <p class="font-bold">{{ $title ?? '通知' }}</p>
    <p>{{ $slot }}</p>
</div>

使用起來就非常簡單:

<!-- In any other Blade file -->

<x-alert type="success">
    <x-slot name="title">
        操作成功!
    </x-slot>
    你的資料已經成功儲存。
</x-alert>

<x-alert type="danger" title="發生錯誤">
    糟糕,系統似乎出了一點問題。
</x-alert>

透過元件化,你的 UI 程式碼庫會變得極度好維護。想改一個按鈕樣式?只需要改一個檔案,全站就都更新了。這才是工程師該有的帥氣!

讓 Blade 保持單純:把你的商業邏輯請出樣板

這是我最想囉嗦的一點,也是新手最容易犯的錯:絕對、絕對不要在 Blade 模板裡寫複雜的商業邏輯!

我敢打賭,你一定看過那種在 @php ... @endphp 區塊裡做資料庫查詢、計算複雜報表、甚至呼叫外部 API 的 Blade 檔。這完全違背了 MVC(Model-View-Controller)的設計原則。View 的唯一職責就是「呈現資料」,它不應該知道也不該關心這些資料是怎麼來的。

壞味道:當 Blade 檔開始「想太多」

看看這個反面教材:

<!-- DO NOT DO THIS! -->
@php
    $user = auth()->user();
    $totalSpent = 0;
    foreach($user->orders as $order) {
        if ($order->is_paid) {
            $totalSpent += $order->amount;
        }
    }
    $level = '銅級會員';
    if ($totalSpent > 10000) {
        $level = '金級會員';
    }
@endphp

<h1>會員等級:{{ $level }}</h1>

這段程式碼讓 Blade 檔案變得臃腫、難以測試,而且邏輯與畫面高度耦合。如果會員等級的計算規則改變了,你還得記得來改這個 Blade 檔。

優雅的解決方案:View Composers 與 Service Injection

那這些邏輯該放哪?

  • 簡單的資料準備: 放在 Controller 裡,處理好再傳給 View。
  • 跨多個 View 的共用資料: 使用 View Composers。你可以在 Service Provider 中註冊一個 Composer,讓它在渲染特定 View 時自動綁定需要的資料。例如網站的側邊欄需要顯示最新文章,就很適合用 View Composer 來處理。
  • 複雜的商業邏輯: 抽離成獨立的 Service Class 或 Action Class,在 Controller 中呼叫它們,再把結果傳給 View。

讓你的 Controller 保持「瘦」,View 保持「笨」,把複雜的工作交給專門的類別去處理,這才是大型專案的長久之計。

效能榨乾術:你不知道的 Blade 進階密技

當你的網站流量上來後,任何一點效能的提升都至關重要。Blade 本身已經非常快了,但我們還可以透過一些技巧把它榨乾!

@include vs. @each:別再傻傻分不清楚

當你需要渲染一個集合的資料時,你可能會用 @foreach 搭配 @include。但其實 Laravel 提供了一個更優雅且可能更高效的方式:@each@each('view.name', $collection, 'variableName') 等同於遍歷集合,並為每個項目 include 指定的 view。

@once:跟重複載入的 JS/CSS 說掰掰

在一個複雜的頁面中,如果多個元件都依賴同一個 JavaScript 函式庫,你可能會不小心載入好幾次。@once 指令可以確保它包住的內容在一次請求的渲染週期中,只會被執行一次。

@once
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
@endonce

@cache:一鍵開啟效能火箭

對於不常變動的區塊,例如網站的頁尾、文章側邊欄的推薦列表,你可以使用 @cache 指令來進行片段快取。Laravel 會把這塊渲染好的 HTML 快取起來,在指定時間內直接從快取讀取,完全跳過重新渲染的過程,效能提升非常有感!

@cache(['popular_posts_sidebar'], 60) <!-- Cache for 60 minutes -->
    <h3>熱門文章</h3>
    <ul>
        @foreach ($popularPosts as $post)
            <li>{{ $post->title }}</li>
        @endforeach
    </ul>
@endcache

安全第一道防線:Blade 的內建安全機制

身為工程師,安全性是絕對不能妥協的底線。幸運的是,Blade 已經幫我們處理了大部分的髒活。

XSS 的天敵:`{{ }}`

Blade 的 `{{ $variable }}` 語法預設會自動將內容通過 PHP 的 `htmlspecialchars` 函式處理,有效防止跨站腳本攻擊(XSS)。這意味著就算變數內容是 `<script>alert(‘hack’)</script>`,它也只會被當成純文字顯示在畫面上,不會被執行。

`{!! !!}`:潘朵拉的盒子,謹慎使用

那如果我真的需要輸出 HTML 呢?例如從一個所見即所得(WYSIWYG)編輯器存下來的內容。這時你可以用 `{!! $variable !!}`。但請務必記住,你必須 100% 確保這些內容是安全、可信的。絕對不要用 `{!! !!}` 來輸出使用者直接輸入的內容,除非你想半夜被叫起來救火,處理網站被駭的問題。

@csrf:表單安全的守護神

只要你在表單中加上 `@csrf` 指令,Laravel 就會自動產生一個隱藏的 token 欄位,用來防禦跨站請求偽造(CSRF)攻擊。這是一個小動作,卻能保護你的應用程式免於重大的安全威脅。請務必在你的所有 `POST`, `PUT`, `PATCH`, `DELETE` 表單中都加上它!

總結:寫出可維護、高效能且安全的 Blade 模板

回顧一下,打造一份優雅的 Blade 模板,你需要掌握:

  • 結構化:善用 @extends, @section, @stack 建立清晰的佈局。
  • 元件化:將重複的 UI 拆分成 <x-component>,告別複製貼上。
  • 職責分離:讓 View 保持單純,把商業邏輯留在後端處理。
  • 效能優化:適時使用 @each, @once, @cache 來榨乾效能。
  • 安全至上:理解 {{ }} 和 `{!! !!}` 的區別,並善用 @csrf

寫程式就像一門手藝,不只是功能的堆砌,更是對結構、可讀性與未來性的考量。希望今天分享的這些 Laravel Blade 模板最佳實務,能幫助你從「會寫」Blade,進階到「寫好」Blade。當你下次打開專案,看到的是一份份清晰如詩的模板時,你會感謝現在願意多花心思的自己。

當然,每個專案都有其獨特的挑戰。如果你在開發 Laravel 或 WordPress 專案時遇到了更複雜的架構問題,或是需要導入更高效能的解決方案,別忘了浪花科技的團隊隨時都在這裡。我們樂於深入研究各種技術難題,並為你的業務打造最穩固的數位基石。

準備好讓你的專案程式碼煥然一新了嗎?歡迎點擊這裡,填寫表單與我們聯繫,讓我們聊聊如何讓你的專案變得更強大!

延伸閱讀

常見問題 (FAQ)

Q1: Blade 模板中可以放複雜的 PHP 邏輯嗎?為什麼不建議?

技術上可以,透過 @php ... @endphp 區塊可以執行任何 PHP 程式碼。但強烈不建議這麼做!這會違反 MVC 設計原則,讓畫面(View)和商業邏輯(Controller/Model)高度耦合,導致程式碼難以閱讀、測試和維護。一個好的實踐是讓 Blade 盡可能「笨」,只負責呈現從 Controller 傳來的資料。

Q2: 傳統的 @component 和匿名組件 (<x-component>) 有什麼不同?我該用哪個?

匿名組件(<x-component>)是 Laravel 7 之後推薦的主流作法,它更直覺、語法更簡潔,適合大多數純粹用於呈現的 UI 元件。傳統的 @component 則通常與一個 Component Class 綁定,當你的元件需要較複雜的邏輯(例如從資料庫獲取資料)時,將邏輯封裝在 Class 中會是更好的選擇。簡單來說,優先使用匿名組件,除非你需要為元件附加特定的後端邏輯。

Q3: View Composer 到底是什麼?什麼時候會需要用到它?

View Composer 是一個回呼函式或類別方法,它會在一個視圖(View)被渲染之前執行。它主要的用途是處理「跨多個頁面的共用資料」。例如,你網站的每一個頁面都需要顯示目前登入的使用者名稱和通知數量,與其在每個 Controller 的每個方法都去抓取一次資料再傳給 View,不如註冊一個 View Composer,讓它自動為所有相關的 View 綁定這些共用資料,讓 Controller 保持乾淨。

Q4: 什麼情況下我才應該使用 `{!! !!}` 來輸出未經轉義的內容?

唯一應該使用 `{!! !!}` 的情況是:你「完全信任」要輸出的內容來源,並且內容本身就是 HTML 格式。最常見的例子就是後台的所見即所得(WYSIWYG)編輯器產生的文章內容。絕對、絕對不要用它來輸出任何來自使用者直接輸入的欄位(例如留言、暱稱),否則將會造成嚴重的 XSS 安全漏洞。

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