Laravel Blade - @ slot/@组件对@include的优势?

Chr*_*sNY 32 php laravel blade laravel-blade laravel-5.4

Laravel 5.4 Blade引入了组件和插槽的概念 - 但我看不出它们在传统的@include上添加了什么.据我所知,使用组件/插槽,您可以:

在模板component-tpl.blade.php中:

<div class='container'>
  <h1>{{$slot1}}</h1>
  <h2>{{$slot2}}</h2>
</div>
Run Code Online (Sandbox Code Playgroud)

使用页面模板中的插槽,您可以:

@component('component-tpl')
  @slot('slot1')
    The content of Slot 1
  @endslot
  @slot('slot2')
    The content of Slot 2
  @endslot
@endcomponent
Run Code Online (Sandbox Code Playgroud)

与旧版本相比,它提供了哪些功能:

@include('component-tpl',['slot1'=>'The content of Slot 1',
'slot2'=>"The content of Slot 2"])
Run Code Online (Sandbox Code Playgroud)

使用完全相同的'component-tpl.blade.php'刀片模板?

我错过了什么?感谢您的任何见解.

克里斯

Ric*_*ick 41

如上所述,没有功能差异,但仔细使用两者都可以为您提供更清晰的刀片文件.

如果插槽可以包含HTML,则使用组件将在刀片文件中提供更清晰的语法.

@component('test')
   <strong>This text has html</strong>
@endcomponent
Run Code Online (Sandbox Code Playgroud)

@include('test', ['slot' => '<strong>This text has HTML</strong>'])
Run Code Online (Sandbox Code Playgroud)

同样,如果组件没有插槽,则可能首选包含:

@include('test')
Run Code Online (Sandbox Code Playgroud)

@component('test')
@endcomponent
Run Code Online (Sandbox Code Playgroud)

  • 这比直接引用文档(令人沮丧的是没有提供任何有用的用例)要有用得多。几周前我刚拿起Laravel,正在从事我的第一个项目。我搜索此文件的原因正是您提供的示例。我有HTML,我不想在字符串中加上`ob_start(); ...返回ob_get_clean()`。 (2认同)

Dav*_*ogo 12

我想我已经找到了另一个重要的区别.例如,从5.4的文档:

Blade的@include指令允许您从另一个视图中包含Blade视图.父视图可用的所有变量都将可用于包含的视图:

据我所知,组件与包含视图的范围不同,因此父视图可用的变量在组件中不可用.您需要将变量传递给这样的组件:

@component('alert', ['foo' => 'bar'])
@endcomponent
Run Code Online (Sandbox Code Playgroud)

此讨论与此问题有关: 在Markdown Mailables中使用变量

  • 这很好,但还有更多内容。检查我上面的答案。 (2认同)

ben*_*ull 9

有两个关键区别。

1. 变量范围

如@DavidHyogo 的回答所述,组件只能看到显式传递给它的变量。所以你必须像这样给它所有的变量......

@component('my-component', ['foo' => 'bar', 'etc' => 'etc'])
Run Code Online (Sandbox Code Playgroud)

而默认情况下包含将采用全局/当前范围内的所有变量- 除非您定义一组显式变量来传递它,然后再次成为局部范围。

{{-- This include will see all variables from the global/current scope --}}
@include('my-component')

{{-- This include will only see the variables explicitly passed in --}}
@include('my-component', ['foo' => 'bar', 'etc' => 'etc']) 
Run Code Online (Sandbox Code Playgroud)

2. 组件的 {{ $slot }} 与包含的 {{ $var }}

在组件中使用 {{ $slot }} 时,您可以为其提供刀片语法代码,例如..

{{-- alert.blade.php --}}
<div class="alert">{{ $slot }}</div>
Run Code Online (Sandbox Code Playgroud)
@component('alert')
    <div>Hello {{ $name }} @include('welcome-message')</div>
@endcomponent
Run Code Online (Sandbox Code Playgroud)

请注意插槽将如何接收 html 和刀片语法代码并对其进行处理。

这对于包含是不可能的,因为您只能将变量传递到包含...

{{-- alert.blade.php --}}
<div class="alert">{{ $slot }}</div>
Run Code Online (Sandbox Code Playgroud)
@include('alert', ['slot' => "I CAN'T PASS IN BLADE SYNTAX HERE!"])
Run Code Online (Sandbox Code Playgroud)

它可以通过获取一个新的 view() 助手并传递一些变量来编译我们想要传递到插槽中的输出来以更hacky的方式完成,但这就是组件的用途。


小智 7

正如文档所说:

组件和插槽为部分和布局提供了类似的好处;然而,有些人可能会发现组件和插槽的心智模型更容易理解

  • 我也阅读了文档,这句话并没有真正帮助我区分两者。我认为 Rick 的一个非常实际的例子确实有助于解开这两种方法。 (4认同)