Form Objects
Extract form logic into dedicated classes for cleaner components and reusable validation.
Basic Usage
Create a Form Object to encapsulate form fields and validation rules:
namespace App\LiVue\Forms;
use LiVue\Attributes\Validate;
use LiVue\Form;
class ContactForm extends Form
{
#[Validate('required|min:2')]
public string $name = '';
#[Validate('required|email')]
public string $email = '';
#[Validate('required|min:10')]
public string $message = '';
}
Using in Component
Component
use App\LiVue\Forms\ContactForm;
class ContactPage extends Component
{
public ContactForm $form;
public function __construct()
{
parent::__construct();
$this->form = new ContactForm();
}
public function submit()
{
$data = $this->form->validate();
// Process the data...
$this->form->reset();
}
}
Template
<form @submit.prevent="livue.call('submit')">
<input v-model="form.name">
<span v-if="livue.errors['form.name']">
{{ livue.errors['form.name'][0] }}
</span>
<input v-model="form.email">
<span v-if="livue.errors['form.email']">
{{ livue.errors['form.email'][0] }}
</span>
<textarea v-model="form.message"></textarea>
<button type="submit">Send</button>
</form>
Available Methods
| Method | Description |
|---|---|
fill($data) |
Populate form from array or model |
all() |
Get all fields as array |
only(['name', 'email']) |
Get only specified fields |
except(['password']) |
Get all except specified fields |
pull() |
Get data and reset form |
reset() |
Reset fields to defaults |
validate() |
Validate and return data (throws on error) |
validateOnly('email') |
Validate a single field |
Create/Edit Pattern
A single Form Object can handle both creating and editing:
class PostForm extends Form
{
public ?Post $post = null;
#[Validate('required|min:5')]
public string $title = '';
#[Validate('required')]
public string $content = '';
public function setPost(Post $post): static
{
$this->post = $post;
$this->fill($post);
return $this;
}
public function save(): Post
{
$validated = $this->validate();
if ($this->post) {
$this->post->update($validated);
return $this->post;
}
$post = Post::create($validated);
$this->reset();
return $post;
}
}
Multiple Forms
A component can have multiple forms with separate validation:
Component
class SettingsPage extends Component
{
public ProfileForm $profile;
public PasswordForm $password;
public function updateProfile()
{
$this->profile->validate();
// ...
}
public function updatePassword()
{
$this->password->validate();
// ...
}
}
Template
<!-- Profile Form -->
<input v-model="profile.name">
<span v-if="livue.errors['profile.name']">
{{ livue.errors['profile.name'][0] }}
</span>
<!-- Password Form -->
<input type="password" v-model="password.current">
<input type="password" v-model="password.new">
Artisan Command
Generate a Form Object with Artisan:
php artisan make:livue-form Contact
# Creates: app/LiVue/Forms/ContactForm.php
Benefits
Cleaner Components
Form logic is extracted, keeping your components focused on behavior.
Reusable Validation
The same Form Object can be used across multiple components.
Testable
Form Objects can be unit tested independently of components.
Type Safety
Typed properties ensure data integrity and IDE support.