PHP 怎么PHP Hotwire

wen PHP项目 1

本文目录导读:

PHP 怎么PHP Hotwire

  1. Hotwire 简介
  2. PHP 集成方案
  3. 关键功能实现
  4. 最佳实践
  5. 部署注意事项
  6. 常见问题解决

我来详细讲解一下 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 中使用时:

  1. 核心是 Turbo 和 Stimulus 的组合
  2. 支持渐进式增强,可以选择性使用
  3. 与 Laravel 集成最佳,但也可以用于其他 PHP 框架
  4. 注意处理 CSRF、错误和认证等安全问题
  5. 可以利用 Turbo Stream 实现实时更新功能

如果你有更具体的需求(比如特定场景的实现),欢迎告诉我,我可以提供更详细的示例!

抱歉,评论功能暂时关闭!