18.1 Blade模板简介

1、Blade 是Laravel 内置的模板引擎,其创建方式是在 resources\views 目录下,创建 模板名.blade.php 的文件,如: user.blade.php ,后缀为:.blade.php ,即可。

2、在控制器中,使用 view()方法来引入模板:

  1. public function user()
  2. {
  3. return view('user');
  4. }

3、模板支持原生PHP 开发。

4、和其它 模板引擎 一样,模板文件被执行后会缓存,而编辑修改后会自动重新缓存。缓存的文件在 storage\framework\views 内。

18.2 模板基础功能

1、在控制器,可以给模板传递变量

//参数2:数组,声明模板变量
return view('user', [
    'name' => '张三' //{{$name}} 模板变量
]);

//facade 方法(需要:use Illuminate\Support\Facades\View):
return View::make('user', [
    'name' => '<br>张三'
]);

然后在模板中,使用模板变量 {{变量名}} 的方式,使用变量:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>标题</title>
</head>
<body>
{{--注释这么写--}}

名字是:{{$name}}
{{--上边这种写法,不会转义,内容当做字符串输出--}}

<hr>

名字是:{!! $name !!}
{{--上边这种写法,会转义,内容当做HTML字符输出--}}

</body>
</html>

2、如果模板页面内容极其简单,也可以直接通过路由加载模板,绕过控制器;

Route::get('/task/user', function () {
    return view('user', [
        'name' => '张三'
    ]);
});

3、如果在模板根目录(resources\views)下建立子目录,调用方法用 点符号 作为路径格式;

如有个文件路径是:resources\views\admin\index.blade.php,那么调用方法:

return view('admin.index');

4、有时可能有判断模板文件是否存在的需求,可以使用exists()方法

//判断模板文件是否存在
return view()->exists('admin.index');

//facade 方法(需要:use Illuminate\Support\Facades\View)
return View::exists('admin.index');

5、可以使用first()方法,加载数组中,存在的第一个模板;

//加载存在于数组中的第一个模板
return view()->first(['abc', 'user', 'def'], [
    'name' => 'Mr.Lee'
]);

//facade 方法(需要:use Illuminate\Support\Facades\View)
return View::first(['abc', 'user', 'def'],[
    'name' => 'Mr.Lee'
]);

18.3 模版的流程控制之条件判断

1、在模版中我们可以使用@if @else @elseif @endif来设置条件判断

2、@unless @endunless 相当于@if 取反的操作,可通过编译文件参看;

3、@isset 判断变量是否存在;@empty 判断变量是否为空;

4、@switch 实现条件分支判断,包含@case @break @default

下面来个总的演示:

首先控制器引入

return view('user', [
    'num' => 20
]);

然后在模板中使用条件判断

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>标题</title>
</head>
<body>
{{--【1】单一判断--}}
@if($num > 10)
    num 大于10
@endif
<hr>

{{--【2】带else 判断--}}
@if($num > 10)
    num 大于10
@else
    num 小于10
@endif
<hr>

{{--【3】带elseif 判断--}}
@if($num > 10)
    num 大于10
@elseif($num > 5)
    num 大于5
@else
    num 小于5
@endif
<hr>

{{--【4】@unless @endunless 相当于@if 取反的操作--}}
@unless($num > 10)
    num 小于10
@endunless
<hr>

{{--【5】@isset 判断变量是否存在--}}
@isset($name)
    变量存在
@endisset
<hr>

{{--【6】@empty 判断变量是否为空--}}
@empty($name)
    变量为空
@endempty
<hr>

{{--【7】@switch 实现条件分支判断--}}
@switch($num)
    @case(1)
    1
    @break
    @case(4)
    4
    @break
    @default
    不存在
@endswitch
<hr>

</body>
</html>

18.4 模版的流程控制之循环遍历

1、@for 循环,适合数值的循环

2、@foreach 适合对象的变量循环

3、@continue 可以跳出当且迭代,@break 跳出循环;

4、@white 判断循环;

示例:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>标题</title>
</head>
<body>

<hr>
{{--@for 循环,适合数值的循环--}}
@for($i =0; $i <= 10; $i++)
    {{$i}}
@endfor

<hr>
{{--@foreach 适合对象的变量循环--}}
@foreach($obj as $user)
    {{$user->username}}
@endforeach
<hr>

{{--@continue 可以跳出当且迭代,@break 跳出循环--}}
@foreach($obj as $user)
    @if ($user->username == '樱桃小丸子')
        @continue //@break
    @endif
    {{$user->username}}
@endforeach

{{--变体写法--}}
@foreach($obj as $user)
    @continue($user->username == '樱桃小丸子')
    {{$user->username}}
@endforeach
<hr>

{{--@white 判断循环--}}
@while($num > 0)
    while 循环
    {{$num--}}
@endwhile
<hr>

</body>
</html>

5、在循环体内,会有一个@loop 变量,帮助我们处理各种问题;

示例:

@foreach($obj as $user)

    @if($loop->first)
        [输出第一组数据之前,执行这里的代码]
    @endif

    @if($loop->last)
        [输出最后一组数据之前,执行这里的代码]
    @endif

    {{--输出数据--}}
    {{$user->username}}  --

@endforeach

更多方法:

属性 说明
$loop->index 当前迭代的索引(从0 开始)
$loop->iteration 当前循环迭代(从1 开始)
$loop->remaining 循环中剩余迭代的个数
$loop->count 被循环的数组元素个数
$loop->first 是否为循环的第一次迭代
$loop->last 是否为循环的最后一次迭代
$loop->even 是否为循环中的偶数次迭代
$loop->odd 是否为循环中的奇数次迭代
$loop->depth 当前循环的嵌套深度
$loop->parent 嵌套循环中的父循环的循环变量

6、PHP 注释和原生的另一种方案@php

@php
    echo 123;
@endphp

18.5 模板的继承布局

为了重复的页面代码更好的管理,可以定义一个父类的模板,其他页面从父类模板中继承代码。

1、首先要定义需要被继承的代码,比如在views 目录下建立public 目录,然后建立父模板base.blade.php;这个base 模板主要存放主体页面的。

为了更好的理解,关闭debug 调试(在config文件下的app.php中设置:’debug’ => (bool) env(‘APP_DEBUG’, false)即可。)

2、然后在正常的模板区域,建立一个子模板index.blade.php,并通过如下代码,即可继承base:

@extends('public.base')

3、父模板通过@yield 设置一个可替换的变量,子模板通过@section 改变变量;

示例:

父模板:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    {{--@yield  参数1 变量名,参数2 默认值--}}
    <title>父模板 -- @yield('title', '未设置标题')</title>
</head>
<body>

<div class="main">
    {{--这里可以写一些共用的模板--}}
    <div>
        这是父模板的内容
    </div>

    {{--下面可以增加子模板自己的内容--}}
@yield('main')

</div>

</body>
</html>

子模板:

{{--继承父模板--}}
@extends('public.base')

{{--改变父模板的变量值--}}
@section('title', '首页')

{{--替换父模板的内容--}}
@section('main')
    <div>
        <p>子区域</p>
    </div>
@endsection

执行后的页面代码为:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">

    <title>父模板 -- 首页</title>
</head>
<body>

<div class="main">

    <div>
        这是父模板的内容
    </div>


    <div>
        <p>子区域</p>
    </div>

</div>

</body>
</html>

4、也可以设置子模板继承父模板的部分内容,具体如下:

父模板:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    {{--@yield  参数1 变量名,参数2 默认值--}}
    <title>父模板 -- @yield('title', '未设置标题')</title>
</head>
<body>

<nav>
    <ol>
        @section('sidebar')
            <li><a href="#">导航</a></li>
        @show
    </ol>
</nav>

</body>
</html>

子模板:

{{--继承父模板--}}
@extends('public.base')

{{--改变父模板的变量值--}}
@section('title', '首页')

{{--替换父模板的内容--}}
@section('sidebar')

    {{--加上 @parent 表示承接父模板该模块内容,如果去掉,则重写父模板的该模块--}}
    @parent

    <li><a href="#">列表</a></li>
@endsection

结果:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">

    <title>父模板 -- 首页</title>
</head>
<body>

<nav>
    <ol>

        {{--因为加上了 @parent ,所以承接父模板该模块内容--}}
        <li><a href="#">导航</a></li>

        <li><a href="#">列表</a></li>
    </ol>
</nav>

</body>
</html>

18.6 其它技巧

1、默认变量会被自动转义,比如特殊符号&,如果不想被转义可以用如下格式:

{!! $name !!}

2、可以使用@json 直接将数组转换成json 格式,参数2 格式化,和原生一样;

@json($list)
@json($list, JSON_PRETTY_PRINT)

示例:

控制类中:

public function index()
{
    return view('user', [
        'list' => [
            'id' => 1001,
            'name' => '张三'
        ]
    ]);
}

模板页面中:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>标题</title>
</head>
<body>

@json($list)
<br>
@json($list, JSON_PRETTY_PRINT)

</body>
</html>

输出结果:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>标题</title>
</head>
<body>

{"id":1001,"name":"\u5f20\u4e09"}<br>
{
    "id": 1001,
    "name": "\u5f20\u4e09"
}

</body>
</html>

3、在 JavaScript 区域,可能也有{{name}}这种模式的操作,和模版变量冲突;

{{--加上@即可防止解析--}}
@{{ name }}

{{--大量JS 时,用范围方式--}}
@verbatim
{{ name }}
@endverbatim

4、如果想让所有模版共享一个变量,在 Providers\AppServiceProvider.php设置全局变量

public function boot()
{
    view()->share('title', '网站的标题');
}

然后在前端页面中,可以直接使用:

<title>{{$title}}</title>

5、给模版传递变量除了 参数2 的数组,也可以使用 with() 方法:

public function index()
{
    return view('user')->with([
        'list' => [
            'id' => 1001,
            'name' => '张三'
        ],
        'title' => '标题'
    ]);
}

以上。