Blade模板基础 #

一、Blade概述 #

1.1 什么是Blade #

Blade是Laravel内置的强大模板引擎。它提供了简洁的语法,支持模板继承、组件、控制结构等功能。

text
Blade特点
├── 简洁语法
│   ├── {{ }} 输出
│   ├── {!! !!} 原始输出
│   └── @指令
├── 模板继承
│   ├── @extends
│   ├── @yield
│   └── @section
├── 组件系统
│   ├── 组件类
│   └── 匿名组件
└── 编译缓存
    └── 自动编译为PHP

1.2 Blade文件位置 #

Blade模板文件存放在 resources/views 目录下,文件扩展名为 .blade.php

text
resources/views/
├── layouts/
│   └── app.blade.php
├── components/
│   └── alert.blade.php
├── users/
│   ├── index.blade.php
│   └── show.blade.php
└── welcome.blade.php

二、显示数据 #

2.1 输出变量 #

blade
<!-- 转义输出 -->
<p>{{ $name }}</p>

<!-- 输出HTML实体 -->
<p>{{ '<script>alert("xss")</script>' }}</p>
<!-- 输出: &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt; -->

2.2 原始输出 #

blade
<!-- 不转义输出(注意XSS风险) -->
<p>{!! $html !!}</p>

2.3 输出JSON #

blade
<script>
    var user = @json($user);
</script>

2.4 默认值 #

blade
<!-- 使用 or 运算符 -->
<p>{{ $name or 'Guest' }}</p>

<!-- 使用 null 合并运算符 -->
<p>{{ $name ?? 'Guest' }}</p>

2.5 调用函数 #

blade
<p>当前时间: {{ now() }}</p>
<p>格式化日期: {{ $user->created_at->format('Y-m-d') }}</p>
<p>大写: {{ strtoupper($name) }}</p>

三、Blade指令 #

3.1 条件判断 #

blade
<!-- if 语句 -->
@if($user)
    <p>欢迎, {{ $user->name }}</p>
@endif

<!-- if-else 语句 -->
@if($user->isAdmin())
    <p>管理员</p>
@else
    <p>普通用户</p>
@endif

<!-- elseif 语句 -->
@if($score >= 90)
    <p>优秀</p>
@elseif($score >= 60)
    <p>及格</p>
@else
    <p>不及格</p>
@endif

<!-- unless 语句(除非) -->
@unless($user->isAdmin())
    <p>您没有管理权限</p>
@endunless

<!-- isset 和 empty -->
@isset($user)
    <p>用户存在</p>
@endisset

@empty($posts)
    <p>没有文章</p>
@endempty

3.2 认证指令 #

blade
<!-- 检查是否登录 -->
@auth
    <p>欢迎回来!</p>
@endauth

@guest
    <p>请登录</p>
@endguest

<!-- 指定守卫 -->
@auth('admin')
    <p>管理员登录</p>
@endauth

3.3 循环 #

blade
<!-- for 循环 -->
@for($i = 0; $i < 10; $i++)
    <p>第 {{ $i }} 次</p>
@endfor

<!-- foreach 循环 -->
@foreach($users as $user)
    <p>{{ $user->name }}</p>
@endforeach

<!-- forelse 循环(带空判断) -->
@forelse($posts as $post)
    <p>{{ $post->title }}</p>
@empty
    <p>没有文章</p>
@endforelse

<!-- while 循环 -->
@while($condition)
    <p>循环内容</p>
@endwhile

3.4 循环变量 #

blade
@foreach($users as $user)
    <tr>
        <td>{{ $loop->index }}</td>          <!-- 索引(从0开始) -->
        <td>{{ $loop->iteration }}</td>      <!-- 迭代次数(从1开始) -->
        <td>{{ $loop->first ? '第一个' : '' }}</td>   <!-- 是否第一个 -->
        <td>{{ $loop->last ? '最后一个' : '' }}</td>  <!-- 是否最后一个 -->
        <td>{{ $loop->count }}</td>          <!-- 总数 -->
        <td>{{ $loop->remaining }}</td>      <!-- 剩余数量 -->
        <td>{{ $loop->even ? '偶数' : '奇数' }}</td>  <!-- 是否偶数索引 -->
        <td>{{ $loop->odd ? '奇数' : '偶数' }}</td>   <!-- 是否奇数索引 -->
        <td>{{ $loop->depth }}</td>          <!-- 嵌套深度 -->
        <td>{{ $user->name }}</td>
    </tr>
@endforeach

3.5 嵌套循环 #

blade
@foreach($categories as $category)
    <h2>{{ $category->name }}</h2>
    @foreach($category->posts as $post)
        <p>{{ $loop->parent->iteration }}.{{ $loop->iteration }} {{ $post->title }}</p>
    @endforeach
@endforeach

四、包含视图 #

4.1 @include指令 #

blade
<!-- 包含子视图 -->
@include('partials.header')

<!-- 传递数据 -->
@include('partials.user-card', ['user' => $user])

<!-- 包含不存在的视图(不报错) -->
@includeIf('partials.sidebar')

<!-- 条件包含 -->
@includeWhen($showFooter, 'partials.footer')

<!-- 包含第一个存在的视图 -->
@includeFirst(['custom.header', 'partials.header'])

4.2 @each指令 #

blade
<!-- 渲染集合 -->
@each('partials.user-card', $users, 'user')

<!-- 带空视图 -->
@each('partials.user-card', $users, 'user', 'partials.empty')

五、注释 #

5.1 Blade注释 #

blade
{{-- 这是Blade注释,不会输出到HTML --}}

5.2 HTML注释 #

blade
<!-- 这是HTML注释,会输出到页面 -->

六、PHP代码 #

6.1 @php指令 #

blade
@php
    $total = 0;
    foreach($items as $item) {
        $total += $item->price;
    }
@endphp

<p>总价: {{ $total }}</p>

6.2 @once指令 #

blade
@once
    <script>
        // 只执行一次的代码
    </script>
@endonce

七、类名和样式 #

7.1 @class指令 #

blade
<div @class([
    'alert',
    'alert-success' => $success,
    'alert-danger' => $error,
])>
    消息内容
</div>

7.2 @style指令 #

blade
<div @style([
    'color: red',
    'font-weight: bold' => $important,
])>
    文本内容
</div>

八、属性 #

8.1 @checked指令 #

blade
<input type="checkbox" @checked($user->active)>

8.2 @selected指令 #

blade
<select>
    <option value="1" @selected($user->status === 1)>激活</option>
    <option value="0" @selected($user->status === 0)>禁用</option>
</select>

8.3 @disabled指令 #

blade
<button @disabled($formSubmitted)>提交</button>

8.4 @readonly指令 #

blade
<input type="text" @readonly($user->isLocked)>

8.5 @required指令 #

blade
<input type="text" @required($field->required)>

九、JavaScript变量 #

9.1 输出JavaScript变量 #

blade
<script>
    var appName = '{{ config('app.name') }}';
    var userId = {{ auth()->id() ?? 'null' }};
</script>

9.2 使用@json #

blade
<script>
    var user = @json($user);
    var settings = @json([
        'theme' => 'dark',
        'lang' => 'zh',
    ]);
</script>

十、URL生成 #

10.1 url函数 #

blade
<a href="{{ url('/') }}">首页</a>
<a href="{{ url('/users', ['id' => 1]) }}">用户</a>

10.2 route函数 #

blade
<a href="{{ route('users.index') }}">用户列表</a>
<a href="{{ route('users.show', $user) }}">用户详情</a>
<a href="{{ route('users.edit', ['user' => 1, 'tab' => 'profile']) }}">编辑</a>

10.3 action函数 #

blade
<a href="{{ action([UserController::class, 'index']) }}">用户列表</a>

10.4 asset函数 #

blade
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<script src="{{ asset('js/app.js') }}"></script>
<img src="{{ asset('images/logo.png') }}">

十一、CSRF字段 #

11.1 表单CSRF #

blade
<form method="POST" action="/users">
    @csrf
    <!-- 表单字段 -->
</form>

11.2 X-CSRF-TOKEN #

blade
<meta name="csrf-token" content="{{ csrf_token() }}">

<script>
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
</script>

十二、堆栈 #

12.1 @push和@stack #

blade
<!-- 在模板中定义堆栈位置 -->
<head>
    @stack('scripts')
</head>

<!-- 向堆栈添加内容 -->
@push('scripts')
    <script src="/example.js"></script>
@endpush

<!-- 预先添加到堆栈开头 -->
@prepend('scripts')
    <script src="/important.js"></script>
@endprepend

十三、原始Blade #

13.1 @verbatim #

blade
@verbatim
    <div>
        {{ 这不会被Blade处理 }}
        {{ $variable }}
    </div>
@endverbatim

十四、最佳实践 #

14.1 视图组织 #

text
resources/views/
├── layouts/           # 布局模板
│   ├── app.blade.php
│   └── admin.blade.php
├── partials/          # 局部视图
│   ├── header.blade.php
│   ├── footer.blade.php
│   └── sidebar.blade.php
├── components/        # 组件
│   ├── alert.blade.php
│   └── card.blade.php
└── users/             # 模块视图
    ├── index.blade.php
    ├── show.blade.php
    └── form.blade.php

14.2 避免业务逻辑 #

blade
{{-- 不推荐:视图中写业务逻辑 --}}
@if(User::where('role', 'admin')->count() > 0)
    ...
@endif

{{-- 推荐:在控制器中处理 --}}
@if($hasAdmins)
    ...
@endif

14.3 使用组件 #

blade
{{-- 不推荐:重复的HTML --}}
<div class="alert alert-success">
    {{ $message }}
</div>

{{-- 推荐:使用组件 --}}
<x-alert type="success" :message="$message" />

十五、总结 #

15.1 核心要点 #

要点 语法
输出 {{ $var }}
原始输出 {!! $html !!}
条件 @if, @elseif, @else
循环 @foreach, @for, @while
包含 @include
CSRF @csrf

15.2 下一步 #

掌握了Blade基础后,让我们继续学习 模板继承与组件,深入了解Blade的高级特性!

最后更新:2026-03-28