[身份验证脚手架] 应用布局如何构建
第5章:应用布局
欢迎回来🐻❄️
在前一章中,我们深入探索了应用的"大脑",了解了后端控制器和表单请求如何安全地处理用户认证。我们学习了数据如何从用户流向路由,再进入使应用运行的PHP逻辑。
现在,让我们将注意力转回应用的视觉层面。当用户登录时,他们会看到仪表板;访问个人资料页面时,界面看起来与仪表板相似,可能共享相同的导航栏和整体样式。Breeze如何确保所有这些页面具有一致的外观,而无需在每个页面上复制粘贴相同的页眉、导航或页脚代码?这就是应用布局概念的闪光点!
问题:重复劳动令人厌倦
想象您正在建造一栋房子,每个房间都需要天花板、墙壁和地板。您会为每个房间从头开始建造这些吗?当然不会!您会为整栋房子建立统一的结构框架,然后填充每个房间的独特细节(如家具、油漆等)。
在Web开发中,许多页面共享共同元素:
- 带有应用标志的页眉
- 带有链接的导航栏(如仪表板、个人资料、设置)
- 带有版权信息的页脚
- 一致的背景颜色和样式
如果必须将这些共同元素放入每个页面文件(如dashboard.blade.php
、profile.blade.php
、settings.blade.php
),那将是大量的重复工作。如果想更改标志,必须编辑数十个文件!这既繁琐又容易出错,且难以维护。
Breeze的应用布局通过提供基础模板来解决这个问题,这些模板定义了应用页面的整体结构和外观。它们就像房子的"结构框架",确保不同部分的一致性。
什么是应用布局?(页面框架)
将应用布局视为**“页面框架"或"包装器”**,用于包裹独特内容。它是页面上元素总体排列的蓝图,为每个页面的独特内容留出特定区域。
Breeze提供两种主要布局,针对不同用户状态设计:
-
认证布局(
AppLayout
):用于用户登录后才能访问的页面。通常包括:- 顶部持久的导航栏(页眉)
- 指向仪表板、个人资料和注销的链接
- 针对移动设备的响应式设计
- 显示特定页面内容(如仪表板小部件或个人资料表单)的中央区域
- 通常还有一个"页面标题"区域
-
访客布局(
GuestLayout
):用于"访客"(未登录用户)可访问的页面。通常是认证相关页面,如:- 登录表单
- 注册表单
- 忘记密码表单
通常更简单,通常只是将主表单内容居中显示,没有复杂的导航栏
这些布局充当一致的"框架",各个页面插入其中,确保应用的每个部分都具有协调的外观和感觉。
如何在页面中使用布局
让我们看看各个页面文件(如login.blade.php
或dashboard.blade.php
)如何使用这些布局。
1. 登录/注册的访客布局
当访问/login
或/register
(未认证用户的页面)时,它们使用GuestLayout
。
示例:login.blade.php
(Blade技术栈)
<!-- 文件:resources/views/auth/login.blade.php(简化版) -->
<x-guest-layout>{{-- 这是登录页面独特内容的位置 --}}<form method="POST" action="{{ route('login') }}"><!-- 邮箱、密码字段、登录按钮放在这里 --><p>这是登录页面的特定内容!</p><!-- ...更多登录表单元素... --></form>
</x-guest-layout>
说明:
<x-guest-layout>
:这是一个特殊的Blade组件。它告诉Laravel用访客布局定义的结构包裹这些标签内的所有内容。<x-guest-layout> ... </x-guest-layout>
内的内容(本例中的登录<form>
)是此页面的独特内容。布局将获取此内容并将其放入自身结构中的特定占位符。
在浏览器中查看时,访客布局(通常居中内容并添加一些基本样式)将包裹您的登录表单。
2. 仪表板/个人资料的认证布局
用户登录后,/dashboard
或/profile
等页面使用AppLayout
。
示例:dashboard.blade.php
(Blade技术栈)
<!-- 文件:resources/views/dashboard.blade.php(简化版) -->
<x-app-layout>{{-- 这是页面标题的特殊"插槽" --}}<x-slot name="header"><h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">{{ __('Dashboard') }}</h2></x-slot>{{-- 这是仪表板页面的独特内容 --}}<div class="py-12"><div class="max-w-7xl mx-auto sm:px-6 lg:px-8"><div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg"><div class="p-6 text-gray-900 dark:text-gray-100">{{ __("您已登录!") }}</div></div></div></div>
</x-app-layout>
说明:
<x-app-layout>
:类似于<x-guest-layout>
,用认证布局包裹内容。<x-slot name="header"> ... </x-slot>
:这是一个命名的"插槽"。AppLayout
专门为页面标题定义了一个区域。放在此x-slot
内的任何内容都会显示在布局的标题区域中。- 带有"您已登录!"的
div
:这是仪表板页面的主要内容。AppLayout
将获取此内容并将其放入主内容区域。
访问仪表板时,您会看到顶部导航、"Dashboard"标题,然后是"您已登录!"消息,所有这些都由AppLayout
无缝集成。
幕后:布局如何构建
让我们深入了解这些布局的工作原理。
布局流程(非代码演练)
代码:Blade组件和视图文件
在Blade技术栈中,布局使用Laravel强大的Blade组件实现。
-
布局视图文件:这些文件定义布局的实际HTML结构。
resources/views/layouts/app.blade.php
(用于认证用户)resources/views/layouts/guest.blade.php
(用于访客用户)
让我们看看
resources/views/layouts/app.blade.php
(简化版):<!-- 文件:resources/views/layouts/app.blade.php(简化版) --> <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"><head><!-- ...元标签、字体、CSS/JS链接... -->@vite(['resources/css/app.css', 'resources/js/app.js'])</head><body class="font-sans antialiased"><div class="min-h-screen bg-gray-100 dark:bg-gray-900">{{-- 包含顶部导航栏 --}}@include('layouts.navigation'){{-- 这是页面标题的占位符(如"Dashboard") --}}@isset($header)<header class="bg-white dark:bg-gray-800 shadow"><div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">{{ $header }} {{-- 来自<x-slot name="header">的内容放在这里 --}}</div></header>@endisset{{-- 这是放置页面独特内容的主内容区域 --}}<main>{{ $slot }} {{-- 不在命名插槽中的内容放在这里 --}}</main></div></body> </html>
app.blade.php
中的关键元素:@include('layouts.navigation')
:将导航栏(包含标志、仪表板链接、个人资料下拉菜单和注销按钮)拉入布局。这就是在每个认证页面上看到它的原因!{{ $header }}
:来自页面(如dashboard.blade.php
)的<x-slot name="header">
内容注入此处。{{ $slot }}
:这是默认插槽。页面中位于<x-app-layout>
内但不在命名插槽(如header
)中的任何内容都将放在这里。
以及简化版的
resources/views/layouts/guest.blade.php
:<!-- 文件:resources/views/layouts/guest.blade.php(简化版) --> <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"><head><!-- ...元标签、字体、CSS/JS链接... -->@vite(['resources/css/app.css', 'resources/js/app.js'])</head><body class="font-sans text-gray-900 antialiased"><div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100 dark:bg-gray-900"><div><a href="/">{{-- 包含一个小应用标志 --}}<x-application-logo class="w-20 h-20 fill-current text-gray-500" /></a></div><div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg">{{ $slot }} {{-- 登录/注册表单内容放在这里 --}}</div></div></body> </html>
guest.blade.php
中的关键元素:- 定义更简单的结构,通常只是居中一个卡片式区域。
{{ $slot }}
:访客页面(如登录表单)的特定内容插入此处。
-
PHP组件类:在
<x-app-layout>
和<x-guest-layout>
标签背后,是小型PHP类,将这些自定义标签链接到各自的Blade视图文件。可以在app/View/Components/
中找到它们。-
App/View/Components/AppLayout.php
:// 文件:app/View/Components/AppLayout.php(简化版) <?phpnamespace App\View\Components;use Illuminate\View\Component; use Illuminate\View\View;class AppLayout extends Component {/*** 获取代表组件的视图/内容*/public function render(): View{// 告诉Laravel使用'layouts.app' Blade文件作为组件的视图return view('layouts.app');} }
-
App/View/Components/GuestLayout.php
:// 文件:app/View/Components/GuestLayout.php(简化版) <?phpnamespace App\View\Components;use Illuminate\View\Component; use Illuminate\View\View;class GuestLayout extends Component {/*** 获取代表组件的视图/内容*/public function render(): View{// 告诉Laravel使用'layouts.guest' Blade文件作为组件的视图return view('layouts.guest');} }
说明: 这些简单的PHP类充当桥梁,告诉Laravel当看到
<x-app-layout>
时,应加载并渲染layouts.app
Blade文件。 -
其他技术栈中的布局(React、Vue、Livewire)
虽然文件名和语法因选择的前端技术栈而异,但布局的概念保持不变。
- React/Vue with Inertia.js:在
resources/js/Layouts/
中找到布局组件。AuthenticatedLayout.jsx
(或TypeScript的.tsx
/Vue的.vue
):这些组件接受children
(用于主要内容)和可能的header
属性,提供相同的结构包装和导航。GuestLayout.jsx
(或.tsx
/.vue
):一个更简单的组件,包裹登录/注册表单。
- Livewire:仍然使用
resources/views/layouts/app.blade.php
和resources/views/layouts/guest.blade.php
文件,类似于Blade,但它们可能包含Livewire组件作为布局部分,如导航栏的<livewire:layout.navigation />
。
无论技术栈如何,Breeze确保应用具有一致的视觉基础,无论用户是否登录。
结论
应用布局是构建可维护且一致的Web应用的基石。Laravel Breeze提供了强大、预构建的布局(认证用户的AppLayout
和访客的GuestLayout
),定义了页面的整体结构。通过使用这些布局,可以避免重复常见元素如导航栏和页脚,使代码更清晰、更易于更新。
我们已经了解到,各个页面只需将其独特内容"插入"这些布局中,就能在整个应用中创建协调且专业的用户体验。
既然已经理解了Breeze提供的架构组件,从路由和控制器到用户界面和布局,我们将深入探索Breeze如何根据您的选择动态安装所有这些部分。
在下一章中,我们将探索breeze:install
命令背后的"魔法":技术栈特定安装逻辑!