laravel笔记-模板
写在前面
时间可贵,善用目录↑
学习Laravel的笔记,仅仅是作为laravel文档笔记,目的是强化对文档的理解,质量不高。
什么是模板
模板就是在视图(View)中的一系列命令,归根结底还是为了方便编写。
因为在html中插入php代码显得不 优雅 乱,还不容易维护。
laravel用的是Blade模板,大多数模板都大同小异。
模板怎么用?
上面写了视图的用法,但是主要写的是如何调用视图和调用视图之前的一些骚操作。
模板这部分就主要说在视图文件内如何使用骚操作。
回到最开始的代码:
<html>
<body>
<!-- 这里是模板的语法 -->
<h1>Hello, {{ $name }}</h1>
</body>
</html>
laravel使用的Blade模板使用{{}}
作为标志符,就是说在{{}}
中的语句会被模板解析器识别,并转换为相应的php语句。
Blade 视图文件使用 .blade.php 文件扩展并存放在 resources/views 目录下。
比如{{ $name }}
会被解析成<?php echo $name; ?>
.
值得一提的是:
所有的 Blade 视图都会被编译成原生 PHP 代码并缓存起来直到被修改,这意味着对应用的性能而言 Blade 基本上是零开销。
Blade 在视图中并不约束你使用 PHP 原生代码。
基本语法
基本的基本:
{{-- 这是注释 --}}
{{-- 这是输出 --}}
Hello, {{ $name }}
{{-- 这是带默认值输出 --}}
{{ $name or 'Default' }}
{{-- 这是使用php函数,对php --}}
{{ time() }}
{{-- 这是告诉模板不编译这部分 --}}
@{{ name }}.
{{-- @verbatim是告诉模板不编译这部分 --}}
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
流程控制:
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
{{-- 除非 --}}
{{-- 只有Auth::check()为false时输出 --}}
@unless (Auth::check())
You are not signed in.
@endunless
{{-- 循环 --}}
@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->index | 当前循环迭代索引 (从0开始). |
$loop->iteration | 当前循环迭代 (从1开始). |
$loop->remaining | 当前循环剩余的迭代 |
$loop->count | 迭代数组元素的总数量 |
$loop->first | 是否是当前循环的第一个迭代 |
$loop->last | 是否是当前循环的最后一个迭代 |
$loop->depth | 当前循环的嵌套层级 |
$loop->parent | 嵌套循环中的父级循环变量 |
继承与包含
大部分网站的大部分页面的布局都是大同小异的,所以我们会想,可不可以把共通的部分提取出来,做成一个类似于父类的东西,然后让其他的模板全部继承它。
模板继承就解决了这个问题。我们可以定义一个’主’页面布局,然后让其他模板继承。
‘主’模板:resources/views/layouts/master.blade.php
<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
子模板:resources/views/child.blade.php
<!-- 继承 -->
@extends('layouts.master')
<!-- 设置title -->
@section('title', 'Page Title')
<!-- 重写sidebar -->
@section('sidebar')
<!-- 调用父模板的语句 -->
@parent
<p>This is appended to the master sidebar.</p>
@endsection
<!-- 定义content -->
@section('content')
<p>This is my body content.</p>
@endsection
关于@section和@yield:
@yield相当于一个占位符。
@section也相当于一个占位符,不过可以预定义一部分内容,在字模板中使用@parent调用。
类似于抽象类中的抽象方法和普通方法(其实并不类似)。
包含就比较简单了,就是在模板中引入另一个模板,引入模板也可以使用传入的参数。
<div>
<!-- 引入resources/views/shared/errors.blade.php -->
@include('shared.errors')
<!-- 引入也可以携带参数 -->
@include('view.name', ['some' => 'data'])
<form>
<!-- Form Contents -->
</form>
</div>
骚操作
迭代包含
就是有一个视图你需要引用它多次,每次传入的数据不一样。
{{-- 我们把$users数组中的每一个值迭代到admin.list模板中并引入 --}}
{{模板名,数组,属性名,空时的模板}}
@each('admin.list', $users, 'user', 'admin.empty')
服务注入
就是在模板中引入服务,我个人感觉类似于在模板中调用自定义php函数。
{{--通过@inject注入--}}
{{--变量名,要解析的服务类名或接口名--}}
@inject('metrics', 'App\Services\MetricsService')
<div>
{{--调用服务--}}
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
组件&插槽
恩,看了好半天,感觉文档说的不清楚。
就是网站中有些小div(不知道用什么词形容,就是一些块)会在很多页面中出现,或者在页面中出现很多次。
他们结构相同但是内容有差别,所以我们可以把它提出来单独写一个文件(就是组件)。
方便在各个位置调用。
我们定义组件的时候会把有差别的地方留出来方便以后填写,这就是插槽~
下面是例子:
比如说我我们定义一个组件用来显示error,姑且命名为error.blade.php
(从这里可以看出来,组件的本质其实就是模板文件)
resources/views/error.blade.php
<!--简简单单一个例子-->
<div class="danger">
<div class="error-title">{{ $title }}</div>
{{看这里,$slot是组件默认的插槽,,所有没有指定的数据都会插到这里}}
{{下边会看到}}
<div class="error-body">{{ $slot }}</div>
</div>
然后我们在一个页面调用这个组件:
比如说resources/views/login.blade.php
{{--假设我们登录的密码错误,调用这个组件输出错误--}}
{{--使用@component调用组件,参数是模板名--}}
@component('error')
{{--使用@slot来填充指定的插槽--}}
@slot('title')
输入错误
@endslot
{{--当我们填充了一些没有指定插槽的数据时--}}
{{--他们会自动插入插槽的$slot参数中--}}
请检查您的密码~
@endcomponent
所以最后在页面F12看到的结构是
<div class="danger">
<div class="error-title">输入错误</div>
<div class="error-body">请检查您的密码~</div>
</div>
是不是很方便~