Laravel 13 Blade 模板详解

摘要

Blade 是 Laravel 强大的模板引擎。本文将深入讲解 Laravel 13 的 Blade 模板,包括:

  • 模板继承与布局
  • 组件与插槽
  • 自定义指令
  • 数据显示与控制结构
  • 实战案例与最佳实践

本文适合希望掌握 Blade 模板的 Laravel 开发者。

1. 模板继承

1.1 定义布局

1
2
3
4
5
6
7
8
9
10
11
12
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html>
<head>
<title>@yield('title')</title>
@stack('styles')
</head>
<body>
@yield('content')
@stack('scripts')
</body>
</html>

1.2 继承布局

1
2
3
4
5
6
7
8
9
10
11
12
{{-- resources/views/home.blade.php --}}
@extends('layouts.app')

@section('title', 'Home')

@section('content')
<h1>Welcome</h1>
@endsection

@push('styles')
<link rel="stylesheet" href="{{ asset('css/home.css') }}">
@endpush

2. 数据显示

2.1 输出数据

1
2
3
4
5
6
7
8
{{-- 转义输出 --}}
{{ $name }}

{{-- 未转义输出(谨慎使用) --}}
{!! $html !!}

{{-- 默认值 --}}
{{ $name or 'Guest' }}

2.2 Blade 语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{{-- JSON 输出 --}}
@json($data)

{{-- 存在性检查 --}}
@isset($user)
{{ $user->name }}
@endisset

{{-- 空值检查 --}}
@empty($posts)
No posts found.
@endempty

{{-- 环境检查 --}}
@production
{{-- 生产环境 --}}
@endproduction

@env('local')
{{-- 本地环境 --}}
@endenv

3. 控制结构

3.1 条件语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@if ($condition)
{{-- 条件为真 --}}
@elseif ($anotherCondition)
{{-- 另一个条件 --}}
@else
{{-- 其他情况 --}}
@endif

@unless($condition)
{{-- 条件为假 --}}
@endunless

@isset($variable)
{{-- 变量存在 --}}
@endisset

3.2 循环语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@for ($i = 0; $i < 10; $i++)
{{ $i }}
@endfor

@foreach ($users as $user)
{{ $user->name }}
@endforeach

@while ($condition)
{{-- 循环体 --}}
@endwhile

@forelse ($posts as $post)
{{ $post->title }}
@empty
No posts found.
@endforelse

3.3 循环变量

1
2
3
4
5
6
7
@foreach ($users as $user)
{{ $loop->index }} {{-- 索引(从 0 开始) --}}
{{ $loop->iteration }} {{-- 迭代次数(从 1 开始) --}}
{{ $loop->first }} {{-- 是否第一个 --}}
{{ $loop->last }} {{-- 是否最后一个 --}}
{{ $loop->count }} {{-- 总数 --}}
@endforeach

4. 组件

4.1 创建组件

1
php artisan make:component Alert

4.2 组件类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
public function __construct(
public string $type = 'info',
public string $message = ''
) {}

public function render()
{
return view('components.alert');
}
}

4.3 组件模板

1
2
3
4
5
{{-- resources/views/components/alert.blade.php --}}
<div class="alert alert-{{ $type }}">
{{ $message }}
{{ $slot }}
</div>

4.4 使用组件

1
2
3
<x-alert type="success" message="Operation successful!">
Additional content here.
</x-alert>

4.5 插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{{-- 组件定义 --}}
<div class="card">
<div class="card-header">
{{ $title }}
</div>
<div class="card-body">
{{ $slot }}
</div>
<div class="card-footer">
{{ $footer }}
</div>
</div>

{{-- 使用 --}}
<x-card>
<x-slot:title>
Card Title
</x-slot>

Card content here.

<x-slot:footer>
Card Footer
</x-slot>
</x-card>

5. 自定义指令

5.1 注册指令

1
2
3
4
5
6
7
8
9
10
11
// app/Providers/AppServiceProvider.php
public function boot(): void
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('Y-m-d H:i:s'); ?>";
});

Blade::if('admin', function () {
return auth()->check() && auth()->user()->isAdmin();
});
}

5.2 使用指令

1
2
3
4
5
@datetime($user->created_at)

@admin
{{-- 管理员内容 --}}
@endadmin

6. 包含视图

6.1 @include

1
2
3
4
5
6
7
@include('partials.header')

@include('partials.header', ['title' => 'Home'])

@includeIf('partials.header', ['title' => 'Home'])

@includeWhen($condition, 'partials.header')

6.2 @each

1
@each('partials.user', $users, 'user', 'partials.empty')

7. 实战案例

7.1 表单组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{{-- resources/views/components/input.blade.php --}}
<div class="form-group">
<label for="{{ $name }}">{{ $label }}</label>
<input
type="{{ $type ?? 'text' }}"
name="{{ $name }}"
id="{{ $name }}"
value="{{ $value ?? old($name) }}"
class="form-control @error($name) is-invalid @enderror"
{{ $attributes }}
>
@error($name)
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
1
2
3
4
5
6
7
{{-- 使用 --}}
<x-input
name="email"
label="Email Address"
type="email"
required
/>

7.2 分页组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{{-- resources/views/components/pagination.blade.php --}}
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
@if ($paginator->onFirstPage())
<li class="disabled"><span>&laquo;</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}">&laquo;</a></li>
@endif

@foreach ($elements as $element)
@if (is_string($element))
<li class="disabled"><span>{{ $element }}</span></li>
@endif

@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="active"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach

@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}">&raquo;</a></li>
@else
<li class="disabled"><span>&raquo;</span></li>
@endif
</ul>
</nav>
@endif

8. 最佳实践

8.1 组件命名

1
2
3
4
5
6
7
{{-- 推荐:kebab-case --}}
<x-user-profile />
<x-alert-message />

{{-- 不推荐 --}}
<xUserProfile />
<xAlertMessage />

8.2 视图组织

1
2
3
4
5
6
7
8
9
10
11
resources/views/
├── layouts/
│ └── app.blade.php
├── components/
│ ├── alert.blade.php
│ └── input.blade.php
├── partials/
│ ├── header.blade.php
│ └── footer.blade.php
└── pages/
└── home.blade.php

9. 总结

Blade 模板引擎提供了强大的模板功能:

  1. 模板继承:灵活的布局系统
  2. 组件系统:可复用的 UI 组件
  3. 自定义指令:扩展模板语法
  4. 控制结构:简洁的条件和循环

参考资料