视图与Blade模板:视图创建与渲染、Blade模板引擎、模板继承与布局、组件与插槽、@include与@each指令
好,咱们今天来聊聊Laravel里最让我觉得「舒服」的部分——视图和Blade模板。
说实话,我最早接触PHP框架时,最头疼的就是HTML和PHP代码混在一起写。那叫一个乱。直到用了Laravel的Blade,我才觉得「嗯,这才对嘛」。
视图创建与渲染
视图是什么?说白了就是展示给用户看的页面。
在Laravel里,视图文件放在 resources/views 目录下。我习惯按模块分文件夹,比如 admin/、user/,这样找起来方便。
创建一个视图很简单。新建一个 .blade.php 文件就行:
<!-- resources/views/welcome.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>我的第一个Blade视图</title>
</head>
<body>
<h1>欢迎来到我的网站</h1>
</body>
</html>
然后在控制器里返回它:
public function index()
{
return view('welcome');
}
如果你放在子文件夹里,用点号分隔:
return view('admin.dashboard');
传数据给视图也很自然。我常用第二种写法:
// 方式一:with方法
return view('profile')->with('name', $name);
// 方式二:第二个参数传数组(我个人偏爱这个)
return view('profile', ['name' => $name, 'age' => 25]);
// 方式三:compact函数(最简洁)
return view('profile', compact('name', 'age'));
compact(),少写几个字,看着也清爽。但变量名必须和视图里用的一致,别搞混了。
Blade模板引擎
Blade是Laravel自带的模板引擎。它不限制你在视图里写原生PHP,但提供了很多语法糖。
输出变量用双花括号:
<p>你好,{{ $name }}</p>
它会自动转义HTML,防止XSS攻击。如果你需要输出原生HTML(比如富文本内容),用 {!! !!}:
<p>{!! $content !!}</p>
{!! !!} 时要确保数据是安全的。我曾经有个项目因为没注意这个,被注入了恶意脚本,排查了好久。从那以后,我只有确认数据来源可靠时才用。
控制结构也很简洁。比如条件判断:
@if (count($users) > 0)
<p>有 {{ count($users) }} 个用户</p>
@else
<p>暂无用户</p>
@endif
循环:
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
你想想看,这比在HTML里写 <?php foreach(...): ?> 舒服多了吧?
模板继承与布局
这是Blade最强大的功能之一。我几乎每个项目都会用。
先创建一个布局文件 layouts/app.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', '默认标题')</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<header>
@include('partials.nav')
</header>
<main>
@yield('content')
</main>
<footer>
@include('partials.footer')
</footer>
</body>
</html>
然后子视图继承它:
@extends('layouts.app')
@section('title', '用户列表')
@section('content')
<h1>所有用户</h1>
@foreach ($users as $user)
<p>{{ $user->name }}</p>
@endforeach
@endsection
这样,所有页面的头部和尾部都统一了。改一处,全站跟着变。
组件与插槽
组件比模板继承更灵活。你可以把一段可复用的UI封装起来。
创建一个组件 resources/views/components/alert.blade.php:
<div class="alert alert-{{ $type }}">
{{ $slot }}
</div>
使用它:
<x-alert type="success">
操作成功完成!
</x-alert>
如果有多个插槽,用命名插槽:
<!-- components/card.blade.php -->
<div class="card">
<div class="card-header">
{{ $header }}
</div>
<div class="card-body">
{{ $slot }}
</div>
</div>
<x-card>
<x-slot name="header">
用户信息
</x-slot>
<p>姓名:张三</p>
<p>邮箱:zhang@example.com</p>
</x-card>
@include与@each指令
@include 用来引入一个子视图。适合拆分重复的小片段。
@include('partials.user-card', ['user' => $user])
被引入的视图可以直接使用传入的变量:
<!-- partials/user-card.blade.php -->
<div class="user-card">
<h3>{{ $user->name }}</h3>
<p>{{ $user->email }}</p>
</div>
@each 是 @include 的循环版本。我坦白说,这个指令我用得不多,但某些场景下确实方便:
@each('partials.user-card', $users, 'user', 'partials.empty')
四个参数分别是:视图名称、数据集合、每次迭代的变量名、没有数据时显示的视图。
@include 加载大量子视图,结果页面加载慢得像蜗牛。后来发现是每个子视图里都做了数据库查询。记住,视图里尽量别做复杂逻辑,数据提前在控制器里准备好。
好了,关于视图和Blade模板,核心内容就这些。总结一下:
- 视图放在
resources/views,用view()返回 - Blade用
{{ }}输出,用@if、@foreach做控制 - 模板继承用
@extends和@yield,适合整体布局 - 组件用
<x->语法,适合复用小块UI @include引入子视图,@each批量引入
你把这些练熟了,Laravel的前端部分基本就拿下了一大半。下一章咱们聊聊更进阶的东西。