Laravel - @yield 和 @section 之间的区别?

Posted

技术标签:

【中文标题】Laravel - @yield 和 @section 之间的区别?【英文标题】:Laravel - Difference between @yield and @section? 【发布时间】:2015-05-18 04:35:33 【问题描述】:

从Laravel docs,您可以使用两种方法在布局中包含“部分”:

<html>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

既然@yield 也可以使用@yield('section', 'Default Content') 传递一些默认内容,那么@yield 是否只是不使用@parent@section 的简写?

@section
    <!-- Nothing here -->
@show

还有哪些不同之处?

【问题讨论】:

【参考方案1】:

只是添加一些小东西,@yield 基本上定义了一个由overwriting 数据注入的部分,如果我们的视图@extends 是父视图,它也可以工作。

现在,当我们overwrite 时,我们会用新的实现完全替换一个实现,就像公司在意识到出现问题时可以决定更改/覆盖其整个技术一样。

不应与override混淆

【讨论】:

【参考方案2】:

最短的答案:

如果您想完全覆盖主布局上的子数据,请在主布局中使用 @yield

如果您想在子级和@parent 上一起使用主数据和子数据,请在主布局中使用@section(或覆盖主布局上的子数据,如@yield

【讨论】:

【参考方案3】:

简短回答:始终使用@yield,除非您想做一些比提供默认string 更复杂的事情。


长答案@yield@section .. @show 都可以在您扩展刀片模板时选择性地被覆盖。您可以使用 @yield 完成的所有操作也可以使用 @section .. @show 完成,但反之则不行。他们是这样做的:

@yield('main')

可以替换为 @section('main') .. @endsection 可以提供默认字符串,但不能提供 HTML!当没有提供 @section('main') .. @endsection 时,默认字符串将显示在子刀片模板中。

@section('main') .. @show

可以替换为 @section('main') .. @endsection 可以提供默认的 HTML 代码。当没有提供 @section('main') 时,默认的 HTML 代码将显示在子刀片模板中。 可替换为 @section('main')@parent .. @endsection 并额外显示默认 HTML 代码。

这里有一些例子:test.blade.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
  </head>
  <body>
    <h1>This is a test</h1>

    @yield('mainA')
    @yield('mainB', 'This is the alternative 1')
    @yield('mainC', '<p>This is the alternative 2</p>')
    @yield('mainD', 'This is the alternative 3')

    @section('testA')
    @show

    @section('testB')
      This is the alternative 4
    @show

    @section('testC')
      <p>This is the alternative 5</p>
    @show

    @section('testD')
      <p>This is the alternative 6</p>
    @show


  </body>
</html>

这是另一个名为 testA.blade.php 的文件,它扩展了另一个刀片文件:

@extends('test')

@section('mainD')
  <div>
    <p>First replacement!</p>
    <hr>
  </div>
@endsection

@section('testC')
  <div>
    <p>Second replacement!</p>
    <hr>
  </div>
@endsection

@section('testD')
  @parent
  <div>
    <p>Additional content</p>
    <hr>
  </div>
@endsection

这就是结果:

【讨论】:

【参考方案4】:

基本上yield('content') 是一个标记。例如,如果你在标签中放一个yield('content'),你说这部分有内容的名称,顺便说一句,你可以在括号内命名任何你想要的东西。它不必满足。它可以是 yield('inside')。或任何你想要的。

然后在要从布局页面导入 html 的子页面中,只需输入 section('name of the section')。 例如,如果您在布局页面中将标题标记为 yield('my_head_band') @section('my_head_band')。

这会将标题从布局页面导入您的子页面。反之亦然,您的正文部分在本例中被命名为内容。

希望这会有所帮助。

【讨论】:

【参考方案5】:

这一行消除了混淆:“请注意,扩展 Blade 布局的视图只会覆盖布局中的部分。布局的内容可以使用部分中的@parent 指令包含在子视图中”。

因此,如果您已经在主布局中定义了 @section,它将被覆盖,除非您在子布局的 @section 中指定 @parent

但对于@yield,它总是从子布局中获取部分。这意味着它总是覆盖 @yield 部分,即使它的默认值定义为 @yield('section', 'Default Content')

我希望这能消除您的困惑。如果您有更多问题,请告诉我。谢谢

【讨论】:

所以要钉住这个家 - @yield 只是不使用 @parent 的 @section 的简写?对吗? 是的,你可以这样说。 @yield 始终用于将内容从子页面获取到母版页面。因此,当 Laravel 执行您的刀片文件时,它首先检查您是否扩展了主布局,如果您扩展了主布局,那么它会切换到主布局并开始获取您已覆盖的 @sections 和主要内容,即@yield 来自子布局。当然,最后,它将刀片格式解析为原始 php,并在 html/css/js 中提供输出。 我还是不明白。 @pvaitonis ,您还对哪一部分感到困惑?让我知道。谢谢 @pvaitonis @include 类似于 php 的 include() 函数,但它仍然可以在其中包含 @sections,如果它有 .blade 扩展名,它的工作方式与子布局。 @yield 仅从子布局中获取适当的 @section

以上是关于Laravel - @yield 和 @section 之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 检查@yield 是不是为空

Laravel5.6(包括和收益)

Laravel 6 @yield() 在 include() 方法中不起作用

Laravel Blade 限制 @yield 结果的字符

为啥我的@yield() 没有显示内容?在 Laravel PHP 模板中

Laravel模板的继承