在 Filament v3.3 中,在非后台页面使用 Forms 功能有几种方式。以下是详细的实现方法:
1. 使用 Livewire 组件方式(推荐)
创建 Livewire 组件
实现 Livewire 组件
<?php
namespace App\Http\Livewire;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Livewire\Component;
use Livewire\WithFileUploads;
class ContactForm extends Component implements HasForms
{
use InteractsWithForms;
use WithFileUploads;
public $name;
public $email;
public $phone;
public $subject;
public $message;
public $attachment;
public $agree_terms = false;
public function mount(): void
{
$this->form->fill();
}
public function getFormSchema(): array
{
return [
TextInput::make('name')
->label('姓名')
->required()
->maxLength(255)
->placeholder('请输入您的姓名'),
TextInput::make('email')
->label('邮箱地址')
->email()
->required()
->placeholder('example@email.com'),
TextInput::make('phone')
->label('联系电话')
->tel()
->placeholder('请输入您的手机号'),
Select::make('subject')
->label('咨询主题')
->options([
'product' => '产品咨询',
'technical' => '技术支持',
'cooperation' => '合作洽谈',
'complaint' => '投诉建议',
'other' => '其他',
])
->required()
->native(false),
Textarea::make('message')
->label('详细内容')
->required()
->rows(5)
->placeholder('请详细描述您的问题或需求...'),
FileUpload::make('attachment')
->label('附件上传')
->acceptedFileTypes(['application/pdf', 'image/*'])
->maxSize(5120)
->directory('contact-attachments')
->preserveFilenames(),
Checkbox::make('agree_terms')
->label('我同意相关服务条款')
->required(),
];
}
public function submit(): void
{
$data = $this->form->getState();
// 处理表单提交逻辑
// 例如保存到数据库、发送邮件等
// 示例:保存数据
// Contact::create($data);
// 显示成功消息
session()->flash('success', '表单提交成功!我们会尽快与您联系。');
// 重置表单
$this->form->fill();
}
public function render()
{
return view('livewire.contact-form');
}
}
创建 Livewire 视图
<!-- resources/views/livewire/contact-form.blade.php -->
<div class="max-w-2xl mx-auto p-6 bg-white rounded-lg shadow-md">
<h2 class="text-2xl font-bold mb-6 text-gray-800">联系我们</h2>
<form wire:submit.prevent="submit" class="space-y-6">
{{ $this->form }}
<div class="flex justify-end">
<button
type="submit"
class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors"
>
提交表单
</button>
</div>
</form>
@if (session()->has('success'))
<div class="mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded">
{{ session('success') }}
</div>
@endif
</div>
2. 在普通 Blade 视图中使用
创建服务类
<?php
namespace App\Services;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Form;
class ContactFormService
{
public static function make(): Form
{
return Form::make()
->schema([
TextInput::make('name')
->label('姓名')
->required(),
TextInput::make('email')
->label('邮箱')
->email()
->required(),
Select::make('department')
->label('部门')
->options([
'sales' => '销售部',
'support' => '技术支持',
'billing' => '财务部',
]),
Textarea::make('message')
->label('留言')
->rows(4),
]);
}
}
在控制器中使用
<?php
namespace App\Http\Controllers;
use App\Services\ContactFormService;
use Illuminate\Http\Request;
class ContactController extends Controller
{
public function create()
{
$form = ContactFormService::make();
return view('contact', compact('form'));
}
public function store(Request $request)
{
$form = ContactFormService::make();
try {
$data = $form->getState($request->all());
// 处理数据
// Contact::create($data);
return redirect()->back()->with('success', '提交成功!');
} catch (\Exception $e) {
return redirect()->back()->with('error', '提交失败:' . $e->getMessage());
}
}
}
Blade 视图
<!DOCTYPE html>
<html>
<head>
<title>联系我们</title>
<!-- 引入 Filament 样式 -->
@filamentStyles
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50">
<div class="min-h-screen py-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="max-w-3xl mx-auto">
<div class="bg-white rounded-lg shadow-md p-6">
<h1 class="text-3xl font-bold text-gray-900 mb-8">联系我们</h1>
<form method="POST" action="{{ route('contact.store') }}">
@csrf
<div class="space-y-6">
{{ $form }}
</div>
<div class="mt-8">
<button type="submit" class="w-full py-3 px-4 bg-blue-600 text-white font-semibold rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
提交信息
</button>
</div>
</form>
@if (session('success'))
<div class="mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded">
{{ session('success') }}
</div>
@endif
@if (session('error'))
<div class="mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded">
{{ session('error') }}
</div>
@endif
</div>
</div>
</div>
</div>
<!-- 引入 Filament 脚本 -->
@filamentScripts
</body>
</html>
3. 配置路由
// routes/web.php
use App\Http\Livewire\ContactForm;
use App\Http\Controllers\ContactController;
// 使用 Livewire 组件
Route::get('/contact-livewire', ContactForm::class)->name('contact.livewire');
// 使用传统控制器方式
Route::get('/contact', [ContactController::class, 'create'])->name('contact.create');
Route::post('/contact', [ContactController::class, 'store'])->name('contact.store');
4. 自定义样式和配置
发布 Filament 资源(如果需要自定义)
自定义 CSS(可选)
/* resources/css/filament-frontend.css */
.filament-forms-component {
margin-bottom: 1.5rem;
}
.filament-forms-label {
font-weight: 600;
margin-bottom: 0.5rem;
display: block;
}
5. 高级功能示例
带条件显示的字段
public function getFormSchema(): array
{
return [
Select::make('contact_type')
->label('联系类型')
->options([
'individual' => '个人',
'company' => '企业',
])
->reactive(),
TextInput::make('company_name')
->label('公司名称')
->visible(fn ($get) => $get('contact_type') === 'company'),
TextInput::make('company_size')
->label('公司规模')
->visible(fn ($get) => $get('contact_type') === 'company'),
];
}
表单验证规则
TextInput::make('email')
->label('邮箱')
->email()
->required()
->rules(['email:rfc,dns']),
TextInput::make('phone')
->label('手机号')
->tel()
->rules(['regex:/^1[3-9]\d{9}$/']),
注意事项
-
确保安装依赖:
-
样式冲突:Filament 使用 Tailwind CSS,确保与现有样式兼容
-
文件上传:使用
WithFileUploadstrait 并配置正确的磁盘 -
性能考虑:Filament Forms 会加载较多资源,考虑按需加载
这种方式让你可以在任何 Laravel 应用中使用 Filament v3.3 的强大表单功能,而不仅限于后台管理界面。