Laravel Blade中的`@yield`和`@include`有什么区别?

53

我正在学习 Laravel(从版本 5.3 开始),这两个 Blade 指令看起来非常相似,唯一的区别是,@include 可以注入父级变量并且可以发送其他变量。

@yield@include 有什么区别?

何时应该使用 @yield

何时应该使用 @include

7个回答

43

@yield 主要用于在布局中定义一个部分。当使用@extends扩展布局时,您可以使用@section指令在视图中定义该部分的内容。

布局通常包含您的HTML、<head><body><header><footer>。您在布局中定义一个区域(@yield),用来容纳继承该模板的页面的内容。

在您的主模板中定义该区域。例如:

<body>
    @yield('content')
</body>

假设你的主页扩展了该布局

@extends('layouts.app')

@section('content')
    // home page content here
@endsection
在主页视图中定义的任何 HTML 内容都将注入到扩展布局中相应的位置,并显示在“内容”部分。 @include 类似于标准的 PHP include ,用于可重用的 HTML。它不像 @yield@section 那样具有父/子关系。
我强烈建议阅读Laravel Blade文档,以获取更全面的说明。

27
你的回答并没有真正回答问题。你刚刚说的是@yield@include都将HTML注入到父文件中。Laravel文档也非常差。它不针对新手使用laravel的人群。@yield@include的主要区别是:@include定义视图注入到父级,而@yield定义要注入的section。只有当你的视图@extends父视图时,@yield才会起作用。 - user1651105
2
我同意之前的评论。我正在阅读关于 Blade 模板的 Laravel 文档(v8.x),但是我很难理解它的工作原理。我理解模板的概念,但 Laravel 并没有详细说明它的结构。他们提供了一些示例,你只能根据这些示例来理解结构。更糟糕的是,许多在线教程只是简单地重复 Laravel 的文档。 - David Tran

26

@include@yield是两种完全不同的操作,用于将代码导入当前文件中。

@include - 将另一个文件的内容导入到当前文件的指定位置。例如:

布局文件:

< some html or other script >

@include('include.file_name') // "include." indicates the subdirectory that the file is in

< more html or other script >

包含文件(一个包含代码块的 Blade 文件):

< some cool code here >

'file_name' 的内容(也是一个 blade 文件)会在 @include 指令所在的位置被导入。

@yield 从子文件(视图 blade 文件)中的 "section" 导入代码,例如:

布局文件:

< some html or other script >

@yield('needed_section_name')

< more html or other script >

需要在“view”刀模板文件中添加以下部分,该文件已经被设置为“扩展”该布局文件。

“View”刀模板文件:

@extends('layout.file_name')
... code as neeeded

@section('needed_section_name')
< some cool code here >
@stop

...
more code as needed

现在布局文件将在与所使用命名相匹配的代码部分中导入。

更多相关内容请参见此处....


3
这确实澄清了它们的不同之处。但是你能分享一个例子,说明yield何时比include更好或更合适吗?因为在两种情况下,你都只是从另一个位置包含代码 - 无论是有选择地包含来自另一个文件的代码还是不包含。 - Spencer Hill
1
这似乎是最好的答案。 - HartleySan
1
这似乎是最好的答案,简而言之 包括=>>所有页面内容 产出=>页面内容的一部分 - Ibrahim Ahmed

7
@yield@include的区别在于使用方式。
如果您有静态内容,例如导航栏,则该页面部分始终位于布局中的相同位置。当您在布局文件中使用@include时,导航栏将每个布局放一次。但是,如果您使用@yield,则必须在每个@extends布局的页面上制作一个@section的导航栏。
另一方面,@yield是在所有页面上更改内容但仍希望在各处使用相同布局的更好选择。如果使用@include,则必须为每个页面创建新布局,因为内容不同。

你可以将一些变量传递到包含文件中,使它们变得“动态”,对吗? - ymakux

4

今天我也在试图弄清楚它们之间的差异,以及何时使用每个,为什么要使用其中一个而不是另一个。请注意,本答案可能会很啰嗦并且解释得太多。

Laracasts论坛的Snapey让我开始认真思考它们:
https://laracasts.com/discuss/channels/laravel/whats-the-difference-between-atinclude-and-atyield

首先,@include将包含整个文件,就像PHP include函数一样。如果您只是将整个内容文件转储到页面的<body>中,那么这非常棒,例如以下内容将包含'content.blade.php'内的所有内容:

<!-- layout.blade.php -->

<body>

@include('content')

</body>

<!-- content.blade.php -->
<div>
    <div>
        <p>Hey this is my content.</p>
    </div>
    <div>
        <span>and stuff</span>
    </div>
</div>

但是,与@extends、@section和@endsection指令一起使用的@yield指令将允许您将内容分块到不同的部分中,但保留在一个文件中。然后,您可以将其分块@yield到布局中。脑海中浮现的视觉效果就像将半张牌洗入另一半牌堆中一样,就像经典的“riffle”洗牌一样:
<!-- content.blade.php -->

@extends('layout')

@section('top_content')
    <h1>Hey I'm the title</h1>
@endsection

@section('middle_content')
    <p>Hey how's it going</p>
@endsection


@section('other_content')
    <p>It's over now.</p>
@endsection

<!-- layout.blade.php -->

<body>

    <div>
        @yield('top_content')
    </div>

    <p>Some static content</p>

    <div>
        @yield('middle_content')
    </div>

    <p>Some more static content</p>

    <div>
        @yield('other_content')
    </div>

    <div>Static footer content of some kind</div>

</body>

其次,更重要的是,控制流有点被倒置了,以一种使得一切更加连贯的方式。在第一个例子中,使用@include时,你会通过视图助手以自上而下的方式调用布局文件。例如,以下是可能是你的代码:
Route::get('/', function () {
    return view('layout');
});

但是使用@yield和@extends(如第二个示例中),您调用内容文件本身,内容文件将首先查看@extends指令以将其自身覆盖在布局文件上,就像穿上外套一样。因此,在某种意义上,它发生了相反的情况,从下到上。然后,@yield指令按指定方式注入内容。内容文件是您在路由器/控制器中要讲话的对象:
Route::get('/', function () {
    return view('content');
});

你调用内容视图,它查看@extends指令以选择布局,然后在布局文件中,@yield指令将匹配的@section部分注入到布局中。因此,这种方式更加有用,因为在实践中,当您引用不同的视图时,将引用不同的内容。如果您只使用@include语句构建视图,则每次都必须向您调用的布局文件传递不同的内容标识符,可能像这样:
Route::get('/welcome', function () {
    return view('layout', ['content' => 'welcome']);
});

Route::get('/profile', function () {
    return view('layout', ['content' => 'profile']);
});

<!-- layout.blade.php -->

<body>

@include($content)

</body>

我觉得那看起来很混乱。

话虽如此,@include 似乎是在你的布局文件(由 @extends 指令调用的文件)中包含一小段代码的好方法,比如导航栏、页脚或者其他你想为了组织目的而分离出来的内容。


2

@include 用于可重复使用的代码,如导航栏,我们只需要设计一次导航栏,就可以在整个网站中使用它。

@yield 用于像主体这样会不断变化的部分。


1

当您的内容将被更改时,应使用@yield。对于不会更改的内容(例如页眉和页脚),应使用@include。


0
例如,您已经拥有自己的布局结构,其中您可以@include(“一些脚本或样式”)。它不允许您更改其指令,而@yield则可以更改其内容。这意味着您可以创建一个section并在layout.blade.php中进行yield。如果每个页面都有特定的脚本或样式,您也可以使用yield。
@include('layouts.nav') //default when you call layout.blade.php

<div class="container"> 
  @yield('content') //changes according to your view
</div>

@include('layouts.footer') //yes you can use @yield if you have specific script.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接