Laravel Blade模板
# 基础
Blade 模板文件使用 .blade.php
作为文件扩展名,存放在 resources/views
目录。
Blade 视图可以使用全局 view
函数从路由或控制器返回。使用 view
的第二参数传递数据到 Blade 视图。
Route::get('/', function () {
return view('welcome', ['name' => 'mrcdh']);
});
2
3
# 显示数据
// web.php
Route::get('/', function () {
return view('welcome', ['name' => 'mrcdh']);
});
// welcome.blade.php
Hello, {{ $name }}.
2
3
4
5
6
7
注意
Blade 的 语句将被 PHP 的
htmlspecialchars
函数自动转义以防范 XSS 攻击。
您不仅限于显示传递给视图的变量的内容。 您也可以回显任何 PHP 函数的结果。 实际上,您可以将所需的任何 PHP 代码放入 Blade echo 语句中:
The current UNIX timestamp is {{ time() }}.
# 渲染 json
<script>
var app = <?php echo json_encode($array); ?>;
</script>
2
3
当然,您亦可使用 @json
Blade 指令来代替手动调用 json_encode
方法。 @json
指令的参数和 PHP 的 json_encode
函数一致:
<script>
var app = @json($array);
var app = @json($array, JSON_PRETTY_PRINT);
</script>
2
3
4
5
注意
使用 @json
指令时,您应该只渲染已经存在的变量为 JSON 。 Blade 模板是基于正则表达式的,如果尝试将一个复杂表达式传递给 @json
指令可能会导致无法预测的错误。
# HTML 实体编码
默认情况下, Blade (以及 Laravel 的帮助函数 e
)会调用 PHP 的 htmlentities
函数来对 HTML 实体进行双重编码。如果不想这样,请在 AppServiceProvider
文件 boot
方法下调用 Blade::withoutDoubleEncoding
方法:
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* 在此启动任意服务
*
* @return void
*/
public function boot()
{
Blade::withoutDoubleEncoding();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 展示非转义数据
Hello, {!! $name !!}.
# Blade 和 javascript 框架
由于许多 JavaScript 框架也使用「花括号」来标识将显示在浏览器中的表达式,因此,您可以使用 @
符号来表示 Blade 渲染引擎应当保持不变。例如:
<h1>Laravel</h1>
Hello, @{{ name }}.
2
3
在这个例子中, @
符号将被 Blade 移除;当然,Blade 将不会修改 表达式,取而代之的是 JavaScript 模板来对其进行渲染。
@
符号也用于转义 Blade 指令:
{{-- 解析输出{"name":"mrcdh"} --}}
@json(['name' => $name])
{{-- 原样输出@json(['name' => $name]) --}}
@@json(['name' => $name])
2
3
4
5
# @verbatim
指令
如果您在模板中显示很大一部分 JavaScript 变量,您可以将 HTML 嵌入到 @verbatim
指令中,这样,您就不需要在每一个 Blade 回显语句前添加 @
符号:
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
2
3
4
5
# Blade 指令
# @if 语句
@if (count($records) === 1)
// 有一条记录
@elseif (count($records) > 1)
// 多条记录
@else
// 没有记录
@endif
2
3
4
5
6
7
# @unless 如果不
@unless ($isAuth)
// 当为 false 时进入,ture 跳过
@endunless
// 等同于
@if (!true)
// ...
@endif
2
3
4
5
6
7
8
# @isset 存在且不为空
@isset($records)
// $records 已经被定义且不为 null ……
@endisset
2
3
# @empty 为空
@empty($records)
// $records 为「空」……
@endempty
2
3
# @switch
@switch($i)
@case(1)
第一个用例 ...
@break
@case(2)
第二个用例 ...
@break
@default
其他用例 ...
@endswitch
2
3
4
5
6
7
8
9
10
11
12
# @for
@for ($i = 0; $i < 10; $i++)
当前的值是 {{ $i }}
@endfor
2
3
# @foreach
@foreach ($users as $user)
<p>这是 {{ $user->id }} 用户</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>没有用户</p>
@endforelse
2
3
4
5
6
7
8
9
可以在循环中使用 $loop
变量来获取一些循环迭代信息。
@foreach ($users as $user)
@if ($loop->first)
这是第一次迭代。
@endif
@if ($loop->last)
这是最后一个迭代。
@endif
<p>This is user {{ $user->id }}</p>
@endforeach
2
3
4
5
6
7
8
9
10
11
属性 | 描述 |
---|---|
$loop->index | 当前循环迭代的索引 (从 0 开始)。 |
$loop->iteration | 在当前循环迭代时 (从 1 开始)。 |
$loop->remaining | 循环中剩余的迭代。 |
$loop->count | 数组中被迭代项的总个数。 |
$loop->first | 这是否是循环的第一次迭代。 |
$loop->last | 这是否是循环的最后一次迭代。 |
$loop->even | 这是否是循环中的偶数迭代。 |
$loop->odd | 这是否是循环中的奇数次迭代。 |
$loop->depth | 当前循环的嵌套级别。 |
$loop->parent | 在嵌套循环中,父循环变量。 |
# @while
@while (true)
<p>我正在循环,直到天荒地老</p>
@endwhile
2
3
# @continue 跳过当前迭代
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
// 简写
@continue($user->type == 1)
@endforeach
2
3
4
5
6
7
# @break 结束循序
@foreach ($users as $user)
@if ($user->number == 5)
@break
@endif
// 简写
@break($user->number == 5)
@endforeach
2
3
4
5
6
7
# @auth 用户通过认证
@auth
// 用户已经通过认证……
@endauth
@auth('admin')
// 指定鉴权守卫
@endauth
2
3
4
5
6
7
# @guest 用户没有通过认证
@guest
// 用户没有通过认证……
@endguest
@guest('admin')
// 指定鉴权守卫
@endguest
2
3
4
5
6
7
# @production 生产环境
@production
// 生产环境执行的逻辑语句……
@endproduction
2
3
# @env 指定环境
@env('staging')
// 该应用运行在 「staging」 环境中...
@endenv
@env(['staging', 'production'])
// 该应用运行在 「staging」和 「production」 环境中...
@endenv
2
3
4
5
6
7
# @include 包含子视图
推荐使用 Balde components
替换该功能。
<div>
{{-- 父视图中的所有变量都可以在子视图中使用 --}}
@include('shared.errors')
<form>
<!-- 表单内容 -->
</form>
</div>
2
3
4
5
6
7
8
尽管子视图可以继承父视图中所有可以使用的数据,但是您也可以传递一个额外的数组,这个数组在子视图中也可以使用:
@include('view.name', ['status' => 'complete'])
# @includeIf 包含一个可能存在也可能不存在的视图
@includeIf('view.name', ['status' => 'complete'])
# @includeWhen 给定值为 true
时包含视图
@includeWhen($boolean, 'view.name', ['status' => 'complete'])
# @includeUnless 给定值为 false
时包含视图
@includeUnless($boolean, 'view.name', ['status' => 'complete'])
# @each 集合渲染视图
- 参数一:要渲染的视图(
view.name
应为列表项的代码片段) - 参数二:遍历的集合
- 参数三:在视图中使用的变量(在
view.name
视图中使用$job
来访问列表项数据,使用$key
来访问当前索引) - 参数四:(可选)当集合为空时渲染的视图
@each('view.name', $jobs, 'job')
@each('view.name', $jobs, 'job', 'view.empty')
2
注意
通过 @each
指令渲染的视图不会继承父视图的变量。如果子视图需要使用这些变量,您可以使用 @foreach
和 @include
来代替它。
# @once 只会渲染计算一次
当引入了 @once
声明的模板视图,无论引入多少次只会计算渲染一次。
@once
<div>666</div>
@endonce
2
3
# @php 原生 PHP
@php
$counter = 1;
@endphp
2
3
# 注释
{{-- 这个注释不会显示到HTML当中 --}}
# 表单相关指令
# @csrf CSRF 字段
<form method="POST" action="/profile">
@csrf
...
</form>
2
3
4
5
# @method('PUT') 设置请求类型
由于 HTML 表单不能发出 PUT
、PATCH
或 DELETE
请求,因此需要添加一个隐藏的 _method
字段来欺骗这些 HTTP 动词。@method
Blade 指令可以为你创建此字段。
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
2
3
4
5
# @error 表单校验错误
@error
指令可用于快速检查给定属性是否存在 验证错误消息 。
在 @error
指令中,可以回显 $message
变量以显示错误消息:
将 特定错误包的名称 作为第二个参数传递给 @error
指令,以便在包含多个表单的页面上检索验证错误消息。
<!-- /resources/views/post/create.blade.php -->
<label for="title">Post Title</label>
<input id="title" type="text" class="@error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
@error('email', 'login')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
2
3
4
5
6
7
8
9
10
11
12
13
# 构件布局
# 使用模板继承布局
# 定义一个布局
<!-- resources/views/layouts/app.blade.php -->
<html>
<head>
<title>App Name - @yield('title', 'mrcdh')</title>
</head>
<body>
@section('sidebar')
这是一个主要的侧边栏
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 继承布局
<!-- 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 指令署名
- 布局文件
@yield
: 显示给定部分的内容。第一个参数用来设置节点名,第二个参数用来设置默认值。@section
,@show
: 定义内容的一部分,设置默认显示内容,并yield
。
- 继承文件
@extends
: 继承布局文件,参数一为布局文件名。@section
: 将内容注入布局节点中(@yield
), 参数一为布局文件的节点名,使用第二个参数直接设置内容。@section
,@endsection
: 将内容注入布局节点中(@yield
), 参数一为布局文件的节点名。@parent
: 将父视图的内容追加到局部视图。