<head><title>@yield('title', 'Default')</title></head>
是 Laravel Blade 模板引擎中 模板继承(Template Inheritance) 的核心语法之一。它允许子视图“注入”内容到布局模板中,同时支持默认值,是实现页面结构复用的关键。
一、知识体系:@yield('title', 'Default')
涉及哪些部分?
1. 模板继承(Template Inheritance)
- Blade 的核心复用机制
- 使用
@extends
让子视图继承布局 - 使用
@yield
、@section
定义可替换区域
{{-- 子视图 --}}
@extends('layouts.app')
@section('title', 'Home')
✅
@yield
是“内容占位符”
2. @yield
指令
- 语法:
@yield('section_name', 'default_value')
- 功能:输出某个 section 的内容,若未定义则使用默认值
- 是“可选内容区域”的标准方式
✅ 类似 Vue 的
<slot>
或 React 的children
3. @section
与 @endsection
- 定义内容块
- 子视图通过
@section('title')
提供内容
@section('title')
Home Page
@endsection
✅ 可嵌套、可追加(
@parent
)
4. 默认值机制
@yield('title', 'Default')
中的'Default'
是默认标题- 当子视图未定义
title
section 时生效 - 提高布局的健壮性
✅ 避免页面无标题
5. 布局模板(Layouts)
- 通常位于
resources/views/layouts/
- 定义
<html>
、<head>
、<body>
等公共结构 - 包含多个
@yield
区域(如content
、scripts
、styles
)
<!-- resources/views/layouts/app.blade.php -->
<html>
<head>
<title>@yield('title', 'My App')</title>
@stack('styles')
</head>
<body>
@yield('content')
@stack('scripts')
</body>
</html>
6. @section
的三种用法
语法 | 说明 |
---|---|
@section('title') ... @endsection | 定义内容块 |
@section('title', 'value') | 简写:定义字符串内容 |
@yield('title', 'default') | 输出内容,带默认值 |
7. 缓冲区(Output Buffering)机制
- Blade 使用 PHP 的
ob_start()
和ob_get_clean()
捕获@section
内容 - 将子视图的内容“捕获”并注入到布局中
✅ 这是
@section
能“反向注入”的关键
8. 堆栈(Stacks)——资源聚合
@stack('scripts')
和@push('scripts')
配合使用- 允许子视图“推送” JS/CSS,布局统一输出
@push('scripts')
<script src="chart.js"></script>
@endpush
✅ 解决“子页面需要额外资源”的问题
9. Blade 编译器
- 将
.blade.php
文件编译为原生 PHP - 缓存到
storage/framework/views/
- 提升运行时性能
10. 与组件系统的对比
机制 | 用途 |
---|---|
@yield / @section | 整体布局继承 |
<x-component> | UI 组件复用(类似 Vue) |
✅ 两者互补,
@yield
更适合页面级结构
二、底层原理:@yield('title', 'Default')
是如何工作的?
我们从 Blade 编译器的执行流程来解析。
🔹 1. 编译流程概览
resources/views/home.blade.php
↓
Blade Compiler 解析 @extends, @section, @yield
↓
生成 PHP 代码(使用 ob_start, include 等)
↓
缓存为 storage/framework/views/xxxx.php
↓
PHP 执行编译后的文件
🔹 2. @yield
的编译结果
<title>@yield('title', 'Default')</title>
被编译为:
<title><?php echo $__env->yieldContent('title', 'Default'); ?></title>
✅ 调用
BladeCompiler
的yieldContent()
方法
🔹 3. @section
的编译结果
@section('title', 'Home')
等价于:
<?php $__env->startSection('title'); ?>
Home
<?php $__env->stopSection(); ?>
编译为:
<?php $__env->startSection('title'); ?>
Home
<?php echo $__env->yieldSection(); ?>
🔹 4. 缓冲区(Output Buffering)机制
Blade 使用 PHP 的输出缓冲区来“捕获” @section
的内容:
// Illuminate/View/Concerns/ManagesLayouts.php
public function startSection($name, $content = null)
{
if ($content === null) {
ob_start();
$this->sectionStack[] = $name;
} else {
$this->sections[$name] = $content;
}
}
public function yieldSection()
{
$last = array_pop($this->sectionStack);
if (ob_get_level()) {
$this->sections[$last] = ob_get_clean();
}
}
执行流程:
- 子视图执行
@section('title')
ob_start()
开启缓冲区- 输出
Home
- 遇到
@endsection
→ob_get_clean()
捕获内容 → 存入$sections['title']
- 布局模板中
@yield('title')
→ 输出$sections['title']
✅ 实现“子视图内容注入布局”
🔹 5. yieldContent()
的实现
public function yieldContent($section, $default = '')
{
if (isset($this->sections[$section])) {
return $this->sections[$section];
}
return $default instanceof Renderable ?
$default->render() : $default;
}
- 检查
$sections
数组中是否有该 section - 有则返回内容
- 无则返回默认值
🔹 6. 模板继承的完整流程
1. 子视图:@extends('layouts.app')
2. Blade 编译器记录继承关系
3. 子视图:@section('title') ... @endsection
→ 使用 ob_start() 捕获内容 → 存入 $sections['title']
4. 子视图编译结束
5. 自动 include 布局模板
6. 布局模板:@yield('title', 'Default')
→ 调用 yieldContent('title', 'Default')
→ 输出捕获的内容或默认值
🔹 7. 编译后的 PHP 代码示例
<?php
// home.blade.php 编译后
$__env->startSection('title'); ?>
Home
<?php echo $__env->yieldSection(); ?>
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>
<?php
// layouts/app.blade.php 编译后
?>
<html>
<head>
<title><?php echo $__env->yieldContent('title', 'Default'); ?></title>
</head>
<body>
<?php echo $__env->yieldContent('content'); ?>
</body>
</html>
三、最佳实践
场景 | 建议 |
---|---|
页面标题 | @yield('title', 'App Name') |
主要内容 | @yield('content') |
可选区域 | 带默认值的 @yield |
必填区域 | 不设默认值,强制子视图定义 |
JS/CSS 聚合 | @stack('scripts') + @push |
✅ 总结
知识体系总览
模块 | 内容 |
---|---|
模板继承 | @extends , @section , @yield |
默认值机制 | @yield('name', 'default') |
缓冲区 | ob_start() / ob_get_clean() |
编译器 | 将 Blade 转为 PHP |
布局系统 | layouts/app.blade.php |
堆栈机制 | @push / @stack |
组件对比 | 与 <x-component> 互补 |
底层原理一句话概括:
@yield('title', 'Default')
通过 Blade 编译器转换为yieldContent()
调用,利用 PHP 输出缓冲区(ob_start)在子视图中捕获@section
定义的内容,存储在$sections
数组中,布局模板在渲染时从该数组读取并输出,未定义时返回默认值,实现了模板继承与内容注入。
掌握这一机制,不仅能理解 Laravel 的视图系统,还能设计可复用的前端架构,是全栈开发的核心技能。