Blade中的@section与@yield等标签介绍

9751次阅读 585人点赞 作者: WuBin 发布时间: 2021-06-30 11:37:15
扫码到手机查看

Laravel 框架中的 Blade 模板引擎,很好用,但是在官方文档中有关 Blade 的介绍并不详细,有些东西没有写出来,而有些则是没有说清楚。

比如,使用中可能会遇到这样的问题:

  1. @yield@section都可以预定义可替代的区块,这两者有什么区别呢?
  2. @section可以用@show,@stop,@overwrite以及@append来结束,又有什么区别呢?

本文试对这些问题做一个比较浅显但是直观的介绍。

blade模板基础使用

Blade 是使用模板继承(template inheritance)区块(sections)。所有的 Blade 模板后缀名都要命名为.blade.php

<!-- 文件存储在 resources/views/layouts/master.blade.php -->
<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show

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

在视图模板中使用 Blade 页面布局

@extends('layouts.master')
@section('title', 'Page Title')
@section('sidebar')
    @parent
    <p>添加在sidebar中的内容</p>
@stop
@section('content')
    <p>替换yield中的内容</p>
@stop

请注意 如果视图继承(extend)了一个 Blade 页面布局会将页面布局中定义的区块用视图的所定义的区块重写。

如果想要将页面布局中的区块内容也能在继承此布局的视图中呈现,那就要在区块中使用@parent语法指令,通过这种方式可以把内容附加到页面布局中,我们会在侧边栏区块或者页脚区块看到类似的使用。

有时候,如您不确定这个区块内容有没有被定义,您可能会想要传一个默认的值给@yield。您可以传入第二个参数作为默认值给@yield

@yield('content', '默认值')

@yield 与 @section

首先,@yield是不可扩展的,如果你要定义的部分没有默认内容让子模板扩展的,那么用@yield($name, $default)的形式会比较方便。如果你在子模板中并没有指定这个区块的内容,它就会显示默认内容,如果定义了,就会显示你定义的内容。

@section则既可以被替代,又可以被扩展,这是最大的区别。

{{-- layout.master --}}
@yield('title','默认标题')

@section('content')
默认的内容
@show
{{-- home.index子模板 --}}
@extends('layout.master')

@section('title')
   @parent  // yield无法扩展,加了parent也无效
   新的标题
@stop

@section('content')
    @parent
     扩展的内容
@stop

上面的例子中,模板用@yield@section分别定义了一个区块,然后在子模板中去定义内容,由于@yield不能被扩展,所以即使加上了@parent也不起作用,输出的内容只有“新的标题”,替换了父模板中的“默认的标题”。因此最终生成的页面只能是“新的标题”,子模板中的内容与父模板中的内容无法共存

@section定义的部分,由于使用了@parent关键字,父模板中的内容会被保留,然后再扩展后添加的内容进去,输出的内容会是 “默认的内容 扩展的内容”。

@section加上@stop,默认是替换(注入),必须用@parent关键字才能扩展。

@show 与 @stop

接下来再说说与 @section 对应的结束关键字,@show,@stop有什么区别呢?

@show指的是执行到此处时将该 section 中的内容输出到页面。

@stop则只是进行内容解析,并且不再处理当前模板中后续对该section的处理,除非用 @override覆盖。

通常来说,在首次定义某个 section 的时候,应该用@show,而在替换它或者扩展它的时候,不应该用@show,应该用@stop
{{-- layout.master --}}
<div id="zoneA">
@section('zoneA')
    AAA
    @show
</div>

<div id="zoneB">
@section('zoneB')
   BBB
   @stop // 没有以@show结束 所以不会显示
</div>

<div id="zoneC">
@section('zoneC')
   CCC
@show
</div>

子模板中:

{{-- page.view --}}
@extends('layout.master')

@section('zoneA')
aaa
@stop

@section('zoneB')
bbb
@stop

@section('zoneC')
ccc
@show

layout.master中,用@stop来结束 "zoneB",由于整个模板体系中,没有以@show结束的 "zoneB" 的定义,因此这个区块不会被显示。

page.view中,用@show定义了 'zoneC',这会在执行到这里时立即显示内容,并按照模板继承机制继续覆盖内容。

因此最终显示的内容会是:

从结果可以看到,zoneB 的内容丢失,因为没有用@show告诉引擎输出这部分的内容,而 zoneC 的内容会显示两次,并且还破坏了layout.master 的页面结构,因为@show出现了两次。

如果我们针对zoneB再来修改一下:

父模板中的zoneB不变,在子模板中的zoneB改变一下:

@section('zoneB')
    bbb
@show

@append 和 @override(仅供参考)

@override并不是在子模板中指明内容替换父模板的默认内容,而是另有用途,那么是如何使用呢?

这又涉及到一个 section 在模板中可以多次使用的问题。也即我们所定义的每一个 section ,在随后的子模板中其实是可以多次出现的。比如:

{{-- 父模板master --}}
<div>
@yield('content')
</div>

在子模板中:

@extends('master')

@section('content')
加一行内容
@append

@section('content')
再加一行内容
@append

@section('content')
加够了,到此为止吧。
@stop

在上例中,我在父级模板中只定义了一个名为 "content" 的 section,而在子模板中三次指定了这个 section 的内容。 这个例子最终的输出是:

<div>
加一行内容
再加一行内容
加够了,到此为止吧。
</div>

三次指定的内容都显示出来了,关键就在于@append这个关键字,它表明“此处的内容添加到”,因此内容会不断扩展。而最后用了@stop,表示这个 section 的处理到此为止

如果在后面继续用@append或者@stop来指定这个section的内容,都不会生效。除非用@override来处理。

@override的意思就是“覆盖之前的所有定义,以这次的为准”。比如:

{{-- master --}}
<div>
@yield('content')
@yield('message')
</div>
<div>
@section('content')
加一行内容
@append
@section('content')
再加一行内容
@append
@section('content')
加够了,结束吧
@stop
@section('content')
都不要了,我说的。
@override
</div>

这个例子和刚才的类似,只不过最后加了一组定义。最终的输出会是:

代码如下:

<div>
都不要了,我说的。
</div>

所以,在正式的项目中,有时候需要对数据进行遍历输出的,可以使用@append,而如果遍历到了某个数据发现前面的都错了呢?用@override就可以全部推翻。

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:bladesectionyield
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9094次阅读 588人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3843次阅读 286人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14071次阅读 914人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12908次阅读 442人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11469次阅读 920人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15588次阅读 1244人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14795次阅读 1205人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    28950次阅读 2273人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    24982次阅读 1925人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录