本文目录导读:

我来详细讲解一下 PHP 如何使用 Hotwire(Turbo + Stimulus)。
Hotwire 简介
Hotwire 是 Basecamp 开发的现代 Web 开发框架,包含:
- Turbo:处理页面导航和部分更新
- Stimulus:轻量级 JavaScript 框架
- Turbo Native:原生移动应用支持
PHP 集成方案
基础安装
# 使用 Composer 安装 composer require hotwired/turbo
配置 Laravel 项目
// config/turbo.php 配置文件示例
return [
'default' => [
'driver' => 'turbo',
],
'turbo' => [
'driver' => 'turbo',
'channel' => 'default',
],
];
在 Blade 模板中引入
<!-- layouts/app.blade.php -->
<!DOCTYPE html>
<html>
<head>@yield('title')</title>
<!-- Turbo 核心 -->
<script src="{{ asset('js/turbo.js') }}" defer></script>
<!-- Stimulus -->
<script src="{{ asset('js/stimulus.js') }}" defer></script>
@vite(['resources/js/stimulus.js', 'resources/js/app.js'])
</head>
<body>
@yield('content')
</body>
</html>
关键功能实现
Turbo Frame(页面局部更新)
<!-- 控制器方法 -->
public function index()
{
$users = User::paginate(10);
return view('users.index', compact('users'));
}
public function show(User $user)
{
return view('users.show', compact('user'));
}
<!-- users/index.blade.php -->
<div id="user-list" class="turbo-frame">
<h2>用户列表</h2>
<div class="users">
@foreach ($users as $user)
<div class="user-item">
<a href="{{ route('users.show', $user) }}" data-turbo-frame="user-detail">
{{ $user->name }}
</a>
</div>
@endforeach
</div>
{{ $users->links() }}
</div>
<!-- 详情区域 -->
<div id="user-detail" class="turbo-frame">
选择用户查看详情
</div>
Turbo Stream(实时更新)
<!-- 控制器 -->
public function store(Request $request)
{
$user = User::create($request->validated());
return response()
->view('users._user_item', ['user' => $user])
->header('Content-Type', 'text/vnd.turbo-stream.html');
}
<!-- _user_item.blade.php -->
<turbo-stream action="append" target="users-list">
<template>
<div class="user-item" id="user-{{ $user->id }}">
{{ $user->name }}
</div>
</template>
</turbo-stream>
Stimulus 集成
// resources/js/stimulus.js
import { Application, Controller } from "@hotwired/stimulus"
window.Stimulus = Application.start()
// 示例控制器
class FormController extends Controller {
static targets = ["name", "email"]
validate() {
if (this.nameTarget.value === '') {
this.element.classList.add('has-error')
event.preventDefault()
}
}
}
// 注册控制器
Stimulus.register("form", FormController)
<!-- 使用 Stimulus 控制器 -->
<form data-controller="form" action="{{ route('users.store') }}" method="POST">
<div>
<label>用户名</label>
<input type="text" name="name" data-form-target="name" data-action="submit->form#validate">
</div>
<div>
<label>邮箱</label>
<input type="email" name="email" data-form-target="email">
</div>
<button type="submit">创建用户</button>
</form>
Turbo Navigation(页面导航)
<!-- 视图中使用 Turbo 导航属性 -->
<a href="{{ route('users.index') }}"
data-turbo-action="advance"
data-turbo-frame="_top">
返回列表
</a>
<!-- 或使用 Turbo Visits -->
<script>
Turbo.visit('/users', { action: "replace" });
</script>
实时更新(WebSocket)
# 安装 Laravel Echo composer require laravel/echo pusher-http-laravel
// 控制器中使用 Turbo Stream
use Hotwired\Turbo\Broadcasters\Broadcaster;
public function broadcastUser(User $user)
{
Toast::success('用户创建成功')
->send();
TurboStream::append('users-list', 'users._user_item')
->broadcastToChannel('users-channel', $user);
}
最佳实践
错误处理
// 自定义异常处理器
class TurboExceptionHandler
{
public function render($request, Exception $exception)
{
if ($request->header('Turbo-Frame')) {
return response()
->view('errors.turbo', ['error' => $exception->getMessage()])
->setStatusCode(422);
}
return parent::render($request, $exception);
}
}
CSRF 保护
<!-- 在 Turbo Frame 中的表单需手动添加 -->
<form action="/users" method="POST">
@csrf
<input type="hidden" name="turbo_stream" value="true">
<!-- 表单字段 -->
</form>
认证系统集成
// 处理认证后的 Turbo 响应
public function authenticate(Request $request)
{
if (Auth::attempt($request->only('email', 'password'))) {
if ($request->expectsTurboFrame()) {
return redirect()->to('/dashboard')->withTurboStream();
}
return redirect()->to('/dashboard');
}
}
部署注意事项
# Vite 配置文件
// vite.config.js
export default {
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
build: {
rollupOptions: {
external: ['@hotwired/turbo', '@hotwired/stimulus']
}
}
}
常见问题解决
页面刷新问题
<!-- 在特定页面禁用 Turbo -->
<body data-turbo="false">
<!-- 页面内容 -->
</body>
兼容性问题
// 检测 Turbo 是否生效
document.addEventListener('turbo:load', () => {
console.log('Turbo 已加载');
});
性能优化
// 使用部分渲染减少请求
public function showPartial(User $user, $partial = 'info')
{
if ($partial === 'info') {
return view('users.partials.info', compact('user'))->withTurboFrame('user-info');
}
}
Hotwire 在 PHP 中使用时:
- 核心是 Turbo 和 Stimulus 的组合
- 支持渐进式增强,可以选择性使用
- 与 Laravel 集成最佳,但也可以用于其他 PHP 框架
- 注意处理 CSRF、错误和认证等安全问题
- 可以利用 Turbo Stream 实现实时更新功能
如果你有更具体的需求(比如特定场景的实现),欢迎告诉我,我可以提供更详细的示例!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播