首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Laravel Blade 模板引擎 @section 指令深度解析:yield/section、show/stop/append/override 差異完全指南

     編輯:PHP 相關知識

Laravel Blade 模板引擎的 @section 相關指令功能強大但文檔不夠詳細,導致開發者常混淆 @yield/@section、@show/@stop/@append/@override 的差異。本文透過實例深度解析各指令行為與最佳實踐。

核心概念:區塊定義與繼承

Blade 提供兩種定義可替換區塊的方式:

指令可繼承擴展預設內容用途
@yield('name', 'default')否支援第二參數單向替換,無法用 @parent
@section('name') ... @show是區塊內容本身雙向:可替換、可擴展

@yield vs @section 實戰比較

父版面:layout.master

<!-- layout.master -->
<html>
<head>
    <title>@yield('title', '預設標題')</title>
</head>
<body>
    @section('content')
        預設的內容
    @show
</body>
</html>

子視圖:home.index

<!-- home.index -->
@extends('layout.master')

@section('title')
    @parent
    新的標題
@stop

@section('content')
    @parent
    擴展的內容
@stop

輸出結果差異

  • @yield('title'):@parent 無效,輸出「新的標題」(完全替換)
  • @section('content'):@parent 生效,輸出「預設的內容 擴展的內容」(擴展模式)

區塊結束指令:@show vs @stop vs @append vs @override

行為對照表

指令輸出時機後續同名區塊主要用途
@show立即輸出並結束被忽略(除非 @override)父版面首次定義區塊
@stop僅解析不輸出覆蓋前者(預設替換模式)子視圖定義/覆蓋區塊
@append不輸出,累積內容繼續累積多次追加內容(如迴圈輸出)
@override輸出並清空前序累積重新開始累積強制覆蓋所有前序定義

@show vs @stop 實例

<!-- layout.master -->
<div id="zoneA">
    @section('zoneA')
        AAA
    @show
</div>

<div id="zoneB">
    @section('zoneB')
        BBB
    @stop
</div>

<div id="zoneC">
    @section('zoneC')
        CCC
    @show
</div>
<!-- page.view -->
@extends('layout.master')

@section('zoneA')
    aaa
@stop

@section('zoneB')
    bbb
@stop

@section('zoneC')
    ccc
@show

輸出結果分析

ccc           // page.view 中 @show 立即輸出
<div class="zoneA">
    aaa       // 子視圖 @stop 覆蓋父版面
</div>

<div class="zoneB">
</div>        // 內容丟失!全程無 @show 輸出

<div class="zoneC">
    ccc       // 父版面 @show 輸出
    ccc       // 子視圖 @show 再次輸出,破壞結構
</div>

關鍵規則

  1. 整個繼承鏈中必須有且只有一個 @show 才會正確輸出
  2. 父版面定義區塊用 @show,子視圖覆蓋用 @stop
  3. 子視圖若用 @show 會導致雙重輸出與結構破壞

@append 與 @override:多重定義與強制覆蓋

@append 累積模式

<!-- master -->
<div>
    @yield('content')
</div>

<!-- subview -->
@extends('master')

@section('content')
    加一行內容
@append

@section('content')
    再加一行內容
@append

@section('content')
    加夠了,到此為止吧
@stop

輸出結果

<div>
    加一行內容
    再加一行內容
    加夠了,到此為止吧
</div>

@override 強制覆蓋

<!-- master -->
<div>
    @section('content')
        加一行內容
    @append
    @section('content')
        再加一行內容
    @append
    @section('content')
        加夠了,結束吧
    @stop
    @section('content')
        都不要了,我說的
    @override
</div>

輸出結果

<div>
    都不要了,我說的
</div>

實戰最佳實踐

1. 標準版面結構

<!-- layouts/app.blade.php -->
<html>
<head>
    @section('meta')
        <meta charset="utf-8">
    @show
    
    @yield('title', '網站標題')
</head>
<body>
    @section('sidebar')
        預設側邊欄
    @show
    
    <main>
        @yield('content')
    </main>
    
    @section('scripts')
        <script src="/app.js"></script>
    @show
</body>
</html>

2. 子視圖正確覆蓋

<!-- pages/home.blade.php -->
@extends('layouts.app')

@section('title')
    @parent
    - 首頁
@stop

@section('sidebar')
    @parent
    <a href="/latest">最新文章</a>
@stop

@section('content')
    首頁專屬內容
@stop

@section('scripts')
    @parent
    <script src="/home.js"></script>
@stop

3. 迴圈中動態累積(@append 應用)

<!-- 父版面 -->
<ul class="nav">
    @section('nav-items')
        <li><a href="/">首頁</a></li>
    @show
</ul>

<!-- 子視圖:動態生成選單 -->
@foreach ($menuItems as $item)
    @section('nav-items')
        <li><a href="{{ $item->url }}">{{ $item->name }}</a></li>
    @append
@endforeach

@section('nav-items')
    <li><a href="/contact">聯絡我們</a></li>
@stop

4. 條件式完全覆蓋(@override 應用)

@foreach ($widgets as $widget)
    @section('widget-area')
        @include("widgets.{$widget->type}")
    @append
@endforeach

@if ($user->isAdmin())
    @section('widget-area')
        @include('widgets.admin-panel')
    @override
@endif

常見錯誤與避坑

錯誤現象修正
子視圖用 @show內容輸出兩次、HTML 結構破壞子視圖統一用 @stop 或 @append
全鏈路缺少 @show區塊內容完全不顯示父版面首次定義必須用 @show
@yield 區塊使用 @parent@parent 無效果,報錯或靜默失敗需擴展請用 @section 定義
巢狀 @section 邏輯混淆難以預測輸出結果避免巢狀,改用 @include 組合

總結

Blade @section 指令體系設計精妙但需精確理解:

  • @yield:單向替換,適合無預設內容區塊
  • @section + @show:雙向擴展,父版面定義標準
  • @stop:子視圖覆蓋標準
  • @append:多重累積,適合迴圈/動態生成
  • @override:強制重置,適合條件式完全覆蓋

掌握「一條鏈路一個 @show」核心原則,配合 @parent 實現擴展而非替換,能構建清晰、可維護的模板繼承體系。實務上建議制定團隊模板規範,統一區塊命名與指令使用模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved