前端
使用 PHP
PHP 和 Blade
过去,大多数 PHP 应用通过简单的 HTML 模板与 PHP echo 语句结合,渲染 HTML 到浏览器,这些 echo 语句会输出在请求过程中从数据库中获取的数据:
<div>
<?php foreach ($users as $user): ?>
Hello, <?php echo $user->name; ?> <br />
<?php endforeach; ?>
</div>
在 Laravel 中,渲染 HTML 的这种方式仍然可以通过视图和 Blade 模板来实现。Blade 是一个极为轻量的模板语言,提供了便捷的简短语法来显示数据、遍历数据等:
<div>
@foreach ($users as $user)
Hello, {{ $user->name }} <br />
@endforeach
</div>
以这种方式构建应用时,表单提交和其它页面交互通常会从服务器接收一个全新的 HTML 文档,整个页面会被浏览器重新渲染。即便到今天,许多应用仍然非常适合通过简单的 Blade 模板来构建其前端。
用户期望的增长
然而,随着用户对 Web 应用期望的提升,许多开发者发现需要构建更加动态的前端,提供更为精致的交互体验。基于此,一些开发者选择开始使用 Vue 和 React 等 JavaScript 框架来构建应用的前端。
还有一些开发者,出于对熟悉的后端语言的偏好,开发了可以在主要使用后端语言的基础上构建现代 Web 应用 UI 的解决方案。例如,在 Rails 生态系统中,这促使了像 Turbo Hotwire 和 Stimulus 这样的库的创建。
在 Laravel 生态系统中,需求的变化促使了 Laravel Livewire 和 Alpine.js 的诞生,这些工具使得开发者可以主要使用 PHP 来创建现代、动态的前端。
Livewire
Laravel Livewire 是一个用于构建动态、现代化、充满活力的 Laravel 驱动前端的框架,类似于 Vue 和 React 等现代 JavaScript 框架构建的前端。
使用 Livewire 时,你将创建 Livewire "组件",这些组件渲染 UI 的一个独立部分,并暴露可以从前端调用和交互的方法和数据。例如,一个简单的 "Counter" 组件可能如下所示:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Counter extends Component
{
public $count = 0;
public function increment()
{
$this->count++;
}
public function render()
{
return view('livewire.counter');
}
}
对应的计数器模板将如下所示:
<div>
<button wire:click="increment">+</button>
<h1>{{ $count }}</h1>
</div>
正如你所看到的,Livewire 使你能够编写新的 HTML 属性,如 wire:click
,这些属性将你的 Laravel 应用的前端和后端连接起来。此外,你可以使用简单的 Blade 表达式来渲染组件的当前状态。
对于许多人来说,Livewire 改变了在 Laravel 中进行前端开发的方式,让他们能够在 Laravel 的舒适环境中构建现代的动态 Web 应用。通常,使用 Livewire 的开发者也会使用 Alpine.js,只在需要的地方将 JavaScript 添加到前端,例如渲染对话框窗口。
如果你是 Laravel 新手,我们建议先熟悉视图和 Blade 的基本用法。然后,查阅官方的 Laravel Livewire 文档,学习如何通过互动 Livewire 组件将你的应用提升到下一个层次。
使用 Vue / React
尽管使用 Laravel 和 Livewire 构建现代前端是可能的,但许多开发者仍然倾向于利用 Vue 或 React 等 JavaScript 框架的强大功能。这使得开发者可以利用通过 NPM 提供的丰富的 JavaScript 包和工具生态系统。
然而,如果没有额外的工具支持,将 Laravel 与 Vue 或 React 配对使用会面临一系列复杂的问题,如客户端路由、数据 hydration 和身份验证。客户端路由通常可以通过使用像 Nuxt 和 Next 这样的 Vue/React 框架来简化;然而,当将 Laravel 这样的后端框架与这些前端框架配合使用时,数据 hydration 和身份验证依然是复杂且繁琐的问题。
此外,开发者还需要维护两个独立的代码仓库,通常需要协调两个仓库的维护、发布和部署。虽然这些问题并非无法克服,但我们认为这不是一种高效或愉快的开发方式。
Inertia
幸运的是,Laravel 提供了两全其美的解决方案。 Inertia 桥接了你的 Laravel 应用程序与现代 Vue 或 React 前端之间的差距,让你在使用 Vue 或 React 构建完整的现代前端时,仍能利用 Laravel 路由和控制器进行路由、数据 hydration 和身份验证——这一切都在一个代码仓库中完成。通过这种方式,你可以享受 Laravel 和 Vue/React 的全部优势,而不会削弱任何一个工具的功能。
在将 Inertia 安装到你的 Laravel 应用程序后,你仍然可以像往常一样编写路由和控制器。然而,控制器返回的将不是 Blade 模板,而是 Inertia 页面:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
use Inertia\Inertia;
use Inertia\Response;
class UserController extends Controller
{
/**
* 显示指定用户的个人资料。
*/
public function show(string $id): Response
{
return Inertia::render('Users/Profile', [
'user' => User::findOrFail($id)
]);
}
}
Inertia 页面对应一个 Vue 或 React 组件,通常存储在应用程序的 resources/js/Pages
目录下。通过 Inertia::render
方法传递给页面的数据将用于 hydration 页面组件的 "props":
<script setup>
import Layout from '@/Layouts/Authenticated.vue';
import { Head } from '@inertiajs/vue3';
const props = defineProps(['user']);
</script>
<template>
<Head title="用户资料" />
<Layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
个人资料
</h2>
</template>
<div class="py-12">
你好,{{ user.name }}
</div>
</Layout>
</template>
如你所见,Inertia 允许你在构建前端时充分利用 Vue 或 React 的全部功能,同时提供一个轻量级的桥梁,将 Laravel 后端与 JavaScript 前端连接起来。
服务器端渲染
如果你担心使用 Inertia,因为你的应用程序需要服务器端渲染,不必担心。Inertia 提供了 对服务器端渲染的支持。而且,当你通过 Laravel Forge 部署应用程序时,确保 Inertia 的服务器端渲染过程始终运行是非常简单的。
Starter Kits
如果你想使用 Inertia 和 Vue / React 来构建前端,你可以利用我们的 Breeze 或 Jetstream 启动套件 来快速启动应用程序的开发。这两个启动套件使用 Inertia、Vue / React、Tailwind 和 Vite 构建了应用程序的后端和前端身份验证流程,让你可以快速开始构建下一个大创意。
资源打包
无论你选择使用 Blade 和 Livewire 还是 Vue / React 和 Inertia 来开发前端,你都可能需要将应用程序的 CSS 打包成生产就绪的资源。当然,如果你选择使用 Vue 或 React 来构建应用程序的前端,你还需要将组件打包成浏览器可用的 JavaScript 资源。
默认情况下,Laravel 使用 Vite 来打包你的资源。Vite 提供了超快的构建时间,并且在本地开发时实现了几乎即时的热模块替换(HMR)。在所有新的 Laravel 应用程序中,包括使用我们启动套件的应用程序,你都可以找到一个 vite.config.js
文件,它加载了我们轻量级的 Laravel Vite 插件,使得 Vite 在 Laravel 应用程序中的使用变得非常愉快。
开始使用 Laravel 和 Vite 的最快方法是使用 Laravel Breeze 启动你的应用程序开发,它是我们最简单的启动套件,通过提供前端和后端身份验证脚手架来加速应用程序的启动。
有关使用 Vite 和 Laravel 的详细文档,请参阅我们 【关于打包和编译资源的专门文档】。 |