04 Blade模板

年高洁
2023-12-01

视图(Blade 模板)

参考手册 Blade 模板

laravel 中的视图默认保存在 resources/views 目录下,视图的扩展名是**.blade.php**,Laravel 视图也称为 Blade 模板,Blade 也就是 MVC 中的 V 层,我们可以之间在控制器中 echo 输出 html 代码,比如像下面:

    public function index()
    {
    		echo '<h1>1</h1>';
    }

视图创建与调用

在复杂的逻辑中 HTML 和我们的业务逻辑混合一起,确实不是一个很好的做法,视图提供了一种方便的方法,可以将所有的 HTML 放在不同的文件中。视图将控制器 / 应用逻辑与显示逻辑分开,并存储在 resources/views 目录下。一个简单的视图如下所示:

<html>
  <body>
    <h1>Hello, world</h1>
  </body>
</html>

将上述代码存储到 resources/views/user.blade.php 后,我们可以使用全局辅助函数 view 将其返回,例如:

    return view('user');

如你所见, 传递给 view 辅助函数的第一个参数对应 resources/views 目录中视图文件的名称,不需要传入文件扩展名。

当然,视图文件也可以嵌套在 resources/views 目录的子目录中。例如,如果你的视图存储在 resources/views/admin/profile.blade.php,则可以这样引用它:

return view('admin/profile');
return view('admin.profile');

注意:视图目录名称中不能包含 . 字符。

Blade 是 Laravel 提供的一个简单而又强大的模板引擎。

向视图传递数据

将上例 user.blade.php 文件进行修改。

<html>
    <body>
        <h1>Hello, {{ $name }}</h1>
    </body>
</html>

修改全局辅助函数 view 将其返回,例如:


    return view('user', ['name' => '徐晓熊']);


第二个参数是应该可供视图使用的数据数组。在这种情况下,我们传递 name 变量,该变量将使用 Blade syntax 在视图中显示。

在视图文件中不能直接访问控制器中的变量,需要在控制器中为视图传递数据。使用 view()函数或 with()函数为视图传递数据

  • 方式 1:通过 view()函数的第 2 个参数传递数据

    return view(模板文件, 数组);

  • 方式 2:通过 with()函数传递数据

    return view(模板文件)->with(数组);

  • 方式 3:通过连续调用 with()函数传递数据

    return view(模板文件)->with(名称, 值)->with(名称, 值)…

compact()函数

compact()函数将多个变量打包成一个数组,其参数是要打包的变量名,返回打包后的数组。

控制器

public function show()
{
    $content = '文本内容';
    $arr = [1, 2];
    $data = compact('content', 'arr');
    return view('show', $data);
}

视图

<body>
  <p>{{ $content }}</p>
  <p>{{ implode(',', $arr) }}</p>
</body>

视图优化

默认情况下,视图是按需编译的。当执行渲染视图的请求时,Laravel 将确定该视图的编译版本是否存在。如果已编译视图存在,Laravel 将比较未编译视图是否已被修改。如果已编译视图不存在,或者未编译视图已被修改,Laravel 将重新编译该视图。
在请求期间编译视图会对性能产生影响,因此 Laravel 提供了 view:cache Artisan 命令来预编译应用中使用的所有视图文件。为了提高性能,你可能希望在部署过程中运行以下命令:

php artisan view:cache

你可以使用 view:clear 命令清除视图缓存:

php artisan view:clear

编译的视图将会存在 storage/framework/views/目录下。

你可以看到,凡是写的有 {{}}的地方都编译成了 echo,而且调用了 e函数,e 函数会使用 htmlentities函数来对 HTML 实体进行双重编码。讲 HTML 代码转成实体字符。函数自动转义以防范 XSS 攻击。

<script>
	alert(123123);
<script>

展示非转义数据

如果不想您的数据被转义,那么您可使用如下的语法:

Hello, {!! $name !!}.

模板变量

您不仅限于显示传递给视图的变量的内容。 您也可以回显任何 PHP 函数的结果。 实际上,您可以将所需的任何 PHP 代码放入 Blade echo 语句中:

The current UNIX timestamp is {{ time() }}.

渲染 JSON

有时,您可能会将数组传递给视图,以将其呈现为 JSON,以便初始化 JavaScript 变量。 例如:

<script>
var app = <?php echo json_encode($array); ?>;
</script>

当然,您亦可使用 @json Blade 指令来代替手动调用 json_encode 方法。 @json 指令的参数和 PHP 的 json_encode 函数一致:

<script>
  var app = @json($array); var app = @json($array, JSON_PRETTY_PRINT);
</script>

控制结构

除了模板继承和显示数据以外, Blade 还为常见的 PHP 控制结构提供了便捷的快捷方式,例如条件语句和循环。这些快捷方式为 PHP 控制结构提供了一个非常清晰、简洁的书写方式,同时,还与 PHP 中的控制结构保持了相似的语法特性。

If 语句

您可以使用 @if@elseif@else@endif 指令构造 if 语句。这些指令功能与它们所对应的 PHP 语句完全一致:

@if (count($records) === 1)
    I have one record!
@elseif (count($records) > 1)
    I have multiple records!
@else
    I don't have any records!
@endif

为了方便, Blade 还提供了一个 @unless 指令:

@unless (Auth::check())
    You are not signed in.
@endunless

除了已经讨论过了的条件指令外, @isset@empty 指令亦可作为它们所对应的 PHP 函数的快捷方式:

@isset($records)
    // $records 已经定义但不为空
@endisset

@empty($records)
    // $records 为空……
@endempty

您可使用 @switch@case@break@default@endswitch 语句来构造 Switch 语句

@switch($i)
    @case(1)
        First case...
        @break

    @case(2)
        Second case...
        @break

    @default
        Default case...
@endswitch

循环

除了条件语句, Blade 还提供了与 PHP 循环结构功能相同的指令。同样,这些语句的功能和它们所对应的 PHP 语法一致

@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

技巧:循环时,您可以使用 循环变量 去获取有关循环的有价值的信息,例如,您处于循环的第一个迭代亦或是处于最后一个迭代。

在使用循环的时候,您可以终止循环或跳过当前迭代:

@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

    <li>{{ $user->name }}</li>

    @if ($user->number == 5)
        @break
    @endif
@endforeach

Loop 变量

循环时,循环内部可以使用 $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 属性访问父级循环:

@foreach ($users as $user)
    @foreach ($user->posts as $post)
        @if ($loop->parent->first)
            This is first iteration of the parent loop.
        @endif
    @endforeach
@endforeach

注释

Blade 也允许您在视图中定义注释。但是,和 HTML 注释不同, Blade 注释不会被包含在应用返回的 HTML 中:

{{-- This comment will not be present in the rendered HTML --}}

PHP

在许多情况下,嵌入 PHP 代码到您的视图中是很有用的。您可以在模板中使用 Blade 的 @php 指令执行原生的 PHP 代码块:

@php
    //
@endphp

表单

CSRF 域

任何您在应用中定义 HTML 表单的时候,您都应该在表单中包含一个隐藏的 CSRF token 域,这样一来, CSRF 保护 中间件便能校验请求。您可以使用 @csrf Blade 指令来生成一个 token 域:

<form method="POST" action="/profile">@csrf ...</form>

方法域

由于 HTML 表单不能够构造 PUTPATCHDELETE 请求,您需要添加隐藏的 _method 域来模拟这些 HTTP 动作。您亦可使用 @method Blade 指令来创建这个方法域:

<form action="/foo/bar" method="POST">
    @method('PUT')

    ...
</form>

引入子视图

Blade 的 @include 指令可用于从另一个视图包含一个 Blade 视图。子视图将继承父视图中所有可用的变量:

<div>
    @include('shared.errors')

    <form>
        <!-- Form Contents -->
    </form>
</div>

除了子视图继承父视图中所有可用的数据,您亦可通过数组将数据传递给子视图:

@include('view.name', ['some' => 'data'])

模板继承

使用模板继承进行布局

布局也可以通过 「模板继承」 创建。在引入 组件 之前,这是构建应用程序的主要方法。

模板继承是我们工作之中最常用的布局方式,他可以向 PHP 类的继承一样方便又灵活的应用。

在我们实际的项目开发中,不同的页面会有公共的头部和底部 共同的样式 接下来我们写个简单的例子。

// resources/views/layouts/app.blade.php
<html>
<head>
    <title>大熊婚恋网- @yield('title','我是默认值')</title>
    <style>
        .header{
            width: 100%;
            height: 100px;
            background-color:#f90;
        }
        .main{
            display: flex;
            width: 100%;
            min-height:500px;
        }
        .ce{
            width: 300px;
            background-color:pink;
        }
        .content{
            width: 100%;
            background-color:#cbd5e0;
        }
        .alert{
            width:300px;
            height:60px;
            background-color: #437bde;
            border-radius:10px;
            text-align:center;
            line-height:60px;
        }
        .alert-error{
            background-color: red;
        }
    </style>
</head>
<body>
  <header class="header"></header>
    <div class="main">
        <div class="ce">
            我是侧边栏
        </div>
        <div class="content">
            @section('content')
                <h1>我是面包屑</h1>
            @show

{{--                @yield('content')--}}
        </div>
    </div>
</body>
</html>

// resources/views/user.blade.php

@extends('layouts.app')

@section('title',"个人中心")

@section('content')
    @parent
        <div>
            <h1>我是个人中心</h1>
        </div>
    @endsection

掌握内容

  • 模板继承
  • 继承布局
  • 显示数据
  • if 语句
  • 鉴权指令
  • Switch 语句
  • 循环
  • Loop 变量
  • 注释
  • PHP 代码
  • 引入子视图
 类似资料: