<head><title>@yield(‘title‘, ‘Default‘)</title></head>,知识体系一共包含哪些部分?底层原理是什么?

<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 区域(如 contentscriptsstyles
<!-- 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>

✅ 调用 BladeCompileryieldContent() 方法


🔹 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();
    }
}
执行流程:
  1. 子视图执行 @section('title')
  2. ob_start() 开启缓冲区
  3. 输出 Home
  4. 遇到 @endsectionob_get_clean() 捕获内容 → 存入 $sections['title']
  5. 布局模板中 @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 的视图系统,还能设计可复用的前端架构,是全栈开发的核心技能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值