Blade 视图文件使用 .blade.php
文件扩展并存放在 resources/views
目录下。
模板继承
@section
定义了一个内容的片段
@section('sidebar')
This is the master sidebar.
@endsection
@yield
用于显示给定片段的内容
@yield('content')
@extends
指令来指定子页面所继承的布局
<!-- 存放在 resources/views/child.blade.php --> @extends('layouts.app') @section('title', 'Page Title') @section('sidebar') @parent <p>This is appended to the master sidebar.</p> @endsection @section('content') <p>This is my body content.</p> @endsection
@parent
指令来追加(而非覆盖)内容到布局的侧边栏,@parent
指令在视图渲染时将会被布局中的内容替换。
Route::get('blade', function () { return view('child'); });
组件/插槽
组件和插槽给片段(section)和布局(layout)带来了方便,不过,有些人会发现组件和插槽的心理模型更容易理解。首先,我们假设有一个可复用的“alert”组件,我们想要在整个应用中都可以复用它:
<!-- /resources/views/alert.blade.php --> <div class="alert alert-danger"> {{ $slot }} </div>
{{ $slot }}
变量包含了我们想要注入组件的内容,现在,要构建这个组件,我们可以使用Blade指令@component
:
@component('alert') <strong>Whoops!</strong> Something went wrong! @endcomponent
有时候为组件定义多个插槽很有用。下面我们来编辑alert组件以便可以注入“标题”,命名插槽可以通过“echoing”与它们的名字相匹配的变量来显示:
<!-- /resources/views/alert.blade.php --> <div class="alert alert-danger"> <div class="alert-title">{{ $title }}</div> {{ $slot }} </div>
现在,我们可以使用指令@slot
注入内容到命名的插槽。任何不在@slot
指令中的内容都会被传递到组件的$slot
变量中:
@component('alert') @slot('title') Forbidden @endslot You are not allowed to access this resource! @endcomponent
传递额外数据到组件
有时候你可能需要传递额外数据到组件,出于这个原因,你可以传递数组数据作为第二个参数到@component
指令,所有数据都会在组件模板中以变量方式生效:
@component('alert', ['foo' => 'bar']) ... @endcomponent
数据显示
return view('welcome', ['name' => 'Samantha']); {{ $name }} The current UNIX timestamp is {{ time() }}. Blade 的 {{}} 语句已经经过 PHP 的 htmlentities 函数处理以避免 XSS 攻击。 {{ isset($name) ? $name : 'Default' }} {{ $name or 'Default' }} {!! $name !!} 使用 @ 符号来告诉 Blade 渲染引擎该表达式应该保持原生格式不作改动 @{{ name }} 如果你在模板中很大一部分显示 JavaScript 变量,那么可以将这部分HTML封装在 @verbatim 指令中,这样就不需要在每个 Blade 输出表达式前加上 @ 前缀: @verbatim <div class="container"> Hello, {{ name }}. </div> @endverbatim
流程控制
@if
, @elseif
, @else
和 @endif
来构造 if
语句
@unless (Auth::check()) You are not signed in. @endunless
循环
@for ($i = 0; $i < 10; $i++) The current value is {{ $i }} @endfor @foreach ($users as $user) <p>This is user {{ $user->id }}</p> @endforeach @forelse ($users as $user) <li>{{ $user->name }}</li> @empty <p>No users</p> @endforelse @while (true) <p>I'm looping forever.</p> @endwhile
跳出循环
@continue
@break
在循环体中使用 $loop
变量
@foreach ($users as $user) @if ($loop->first) This is the first iteration. @endif @if ($loop->last) This is the last iteration. @endif <p>This is user {{ $user->id }}</p> @endforeach
通过 $loop
变量的 parent
属性访问父级循环:
属性 | 描述 |
---|---|
$loop->index |
当前循环迭代索引 (从0开始) |
$loop->iteration |
当前循环迭代 (从1开始) |
$loop->remaining |
当前循环剩余的迭代 |
$loop->count |
迭代数组元素的总数量 |
$loop->first |
是否是当前循环的第一个迭代 |
$loop->last |
是否是当前循环的最后一个迭代 |
$loop->depth |
当前循环的嵌套层级 |
$loop->parent |
嵌套循环中的父级循环变量 |
注释
{{-- This comment will not be present in the rendered HTML --}}
PHP原生输出
@php // @endphp
包含子视图
@include
<div> @include('shared.errors') <form> <!-- Form Contents --> </form> </div>
<code>@include('view.name', ['some' => 'data'])
</code>
注:不要在 Blade 视图中使用
__DIR__
和__FILE__
常量,因为它们会指向缓存视图的路径。
渲染集合视图
@each
指令通过一行代码循环引入多个局部视图:
@each('view.name', $jobs, 'job')
该指令的第一个参数是数组或集合中每个元素要渲染的局部视图,第二个参数是你希望迭代的数组或集合,第三个参数是要分配给当前视图的变量名。举个例子,如果你要迭代一个 jobs
数组,通常你需要在局部视图中访问 $job
变量。在局部视图中可以通过 key
变量访问当前迭代的键。
你还可以传递第四个参数到 @each
指令,该参数用于指定给定数组为空时渲染的视图:
@each('view.name', $jobs, 'job', 'view.empty')
堆栈
Blade 允许你推送内容到命名堆栈,以便在其他视图或布局中渲染。这在子视图中引入指定 JavaScript 库时很有用:
<code>@push('scripts')
<script src="/example.js"></script>
@endpush
</code>
推送次数不限,要渲染完整的堆栈内容,传递堆栈名称到 @stack
指令即可:
<code><head>
<!-- Head Contents -->
@stack('scripts')
</head>
</code>
8、服务注入
@inject
指令可以用于从服务容器中获取服务,传递给 @inject
的第一个参数是服务将要被分配到的变量名,第二个参数是要解析的服务类名或接口名:
<code>@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
</code>
9、扩展 Blade
Blade 甚至还允许你自定义指令,可以使用 directive
方法来注册一个指令。当 Blade 编译器遇到该指令,将会传入参数并调用提供的回调。
下面的例子创建了一个 @datetime($var)
指令格式化给定的 DateTime
的实例 $var
:
<code><?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function($expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
/**
* 在容器中注册绑定.
*
* @return void
*/
public function register()
{
//
}
}
</code>
正如你所看到的,我们可以将 format
方法应用到任何传入指令的表达式上。最终该指令生成的 PHP 代码如下:
<code><?php echo ($var)->format('m/d/Y H:i'); ?>
</code>
注:更新完 Blade 指令逻辑后,必须删除所有的 Blade 缓存视图。缓存的 Blade 视图可以通过 Artisan 命令
view:clear
移除。