You're browsing the documentation for an old version of Livewire. Consider upgrading your project to Livewire 3.x.
Be amazing at Livewire
with our in-depth screencasts. Watch Now
- Introduction
- Important Notes
- Initializing Properties
- Data Binding
- Binding Nested Data
- Debouncing Input
- Lazy Updating
- Deferred Updating
- Binding Directly To Model Properties
- Custom (Wireable) Properties
- Computed Properties
Introduction
Livewire components store and track data as public properties on the component class.
1class HelloWorld extends Component
2{
3 public $message = 'Hello World!';
4 ...
Public properties in Livewire are automatically made available to the view. No need to explicitly pass them into the view (although you can if you want).
1class HelloWorld extends Component
2{
3 public $message = 'Hello World!';
4}
1<div>
2 <h1>{{ $message }}</h1>
3 <!-- Will output "Hello World!" -->
4</div>
Important Notes
Here are three ESSENTIAL things to note about public properties before embarking on your Livewire journey:
- Property names can't conflict with property names reserved for Livewire (e.g.
rules
ormessages
) - Data stored in public properties is made visible to the front-end JavaScript. Therefore, you SHOULD NOT store sensitive data in them.
- Properties can ONLY be either JavaScript-friendly data types (
string
,int
,array
,boolean
), OR one of the following PHP types:Stringable
,Collection
,DateTime
,Model
,EloquentCollection
.
protected
and private
properties DO NOT persist between Livewire updates. In general, you should avoid using them for storing state.
You should also note that while null
data type is Javascript-friendly, public
properties set to null
DO NOT persist between Livewire updates.
Initializing Properties
You can initialize properties using the mount
method of your component.
1class HelloWorld extends Component
2{
3 public $message;
4
5 public function mount()
6 {
7 $this->message = 'Hello World!';
8 }
9}
Livewire also makes a $this->fill()
method available to you for cases where you have to set lots of properties and want to remove visual noise.
1public function mount()
2{
3 $this->fill(['message' => 'Hello World!']);
4}
Additionally, Livewire offers $this->reset()
and $this->resetExcept()
to programmatically reset public property values to their initial state. This is useful for cleaning input fields after performing an action.
1public $search = '';
2public $isActive = true;
3
4public function resetFilters()
5{
6 $this->reset('search');
7 // Will only reset the search property.
8
9 $this->reset(['search', 'isActive']);
10 // Will reset both the search AND the isActive property.
11
12 $this->resetExcept('search');
13 // Will only reset the isActive property (any property but the search property).
14}
Data Binding
If you've used front-end frameworks like Vue, or Angular, you are already familiar with this concept. However, if you are new to this concept, Livewire can "bind" (or "synchronize") the current value of some HTML element with a specific property in your component.
1class HelloWorld extends Component
2{
3 public $message;
4}
1<div>
2 <input wire:model="message" type="text">
3
See AlsoGetting Started with Laravel Livewire — SitePointRudi: AI is the end of investing as we know itLaravel Livewire [In-Depth Tutorial] | GoLinuxCloudWhy the time to own Australia's Big Four banks is not now (and where you should invest instead)4 <h1>{{ $message }}</h1>
5</div>
When the user types something into the text field, the value of the $message
property will automatically update.
Internally, Livewire will listen for an input
event on the element, and when triggered, it will send an AJAX request to re-render the component with the new data.
You can add wire:model
to any element that dispatches an input
event. Even custom elements, or third-party JavaScript libraries.
Common elements to use wire:model
on include:
Element Tag |
---|
<input type="text"> |
<input type="radio"> |
<input type="checkbox"> |
<select> |
<textarea> |
Binding Nested Data
Livewire supports binding to nested data inside arrays using dot notation:
1<input type="text" wire:model="parent.message">
Debouncing Input
By default, Livewire applies a 150ms debounce to text inputs. This avoids too many network requests being sent as a user types into a text field.
If you wish to override this default (or add it to a non-text input), Livewire offers a "debounce" modifier. If you want to apply a half-second debounce to an input, you would include the modifier like so:
1<input type="text" wire:model.debounce.500ms="name">
Lazy Updating
By default, Livewire sends a request to the server after every input
event (or change
in some cases). This is usually fine for things like <select>
elements that don't typically fire rapid updates, however, this is often unnecessary for text fields that update as the user types.
In those cases, use the lazy
directive modifier to listen for the native change
event.
1<input type="text" wire:model.lazy="message">
Now, the $message
property will only be updated when the user clicks away from the input field.
Deferred Updating
In cases where you don't need data updates to happen live, Livewire has a .defer
modifier that batches data updates with the next network request.
For example, given the following component:
1<input type="text" wire:model.defer="query">
2<button wire:click="search">Search</button>
As the user types into the <input>
field, no network requests will be sent. Even if the user clicks away from the input field and onto other fields on the page, no requests will be sent.
When the user presses "Search", Livewire will send ONE network request that contains both the new "query" state, AND the "search" action to perform.
This can drastically cut down on network usage when it's not needed.
Binding Directly To Model Properties
If an Eloquent model is stored as a public property on a Livewire component, you can bind to its properties directly. Here is an example component:
1use App\Post;
2
3class PostForm extends Component
4{
5 public Post $post;
6
7 protected $rules = [
8 'post.title' => 'required|string|min:6',
9 'post.content' => 'required|string|max:500',
10 ];
11
12 public function save()
13 {
14 $this->validate();
15
16 $this->post->save();
17 }
18}
1<form wire:submit.prevent="save">
2 <input type="text" wire:model="post.title">
3
4 <textarea wire:model="post.content"></textarea>
5
6 <button type="submit">Save</button>
7</form>
Notice in the above component we are binding directly to the "title" and "content" model attributes. Livewire will take care of hydrating and dehydrating the model between requests with the current, non-persisted data.
Note: For this to work, you need to have a validation entry in the `$rules` property for any model attributes you want to bind to. Otherwise, an error will be thrown.
Additionally, you can bind to models within an Eloquent Collection.
1use App\Post;
2
3class PostForm extends Component
4{
5 public $posts;
6
7 protected $rules = [
8 'posts.*.title' => 'required|string|min:6',
9 'posts.*.content' => 'required|string|max:500',
10 ];
11
12 public function mount()
13 {
14 $this->posts = auth()->user()->posts;
15 }
16
17 public function save()
18 {
19 $this->validate();
20
21 foreach ($this->posts as $post) {
22 $post->save();
23 }
24 }
25}
1<form wire:submit.prevent="save">
2 @foreach ($posts as $index => $post)
3 <div wire:key="post-field-{{ $post->id }}">
4 <input type="text" wire:model="posts.{{ $index }}.title">
5
6 <textarea wire:model="posts.{{ $index }}.content"></textarea>
7 </div>
8 @endforeach
9
10 <button type="submit">Save</button>
11</form>
Livewire also supports binding to relationships on Eloquent models like so:
1class EditUsersPosts extends Component
2{
3 public User $user;
4
5 protected $rules = [
6 'user.posts.*.title'
7 ];
8
9 public function save()
10 {
11 $this->validate();
12
13 $this->user->posts->each->save();
14 }
15}
1<div>
2 @foreach ($user->posts as $i => $post)
3 <input type="text" wire:model="user.posts.{{ $i }}.title" />
4
5 <span class="error">
6 @error('user.posts.'.$i.'.title') {{ $message }} @enderror
7 </span>
8 @endforeach
9
10 <button wire:click="save">Save</button>
11</div>
Custom (Wireable) Properties
Sometimes you may want to set a component property to a non-model object that's available inside your app, like a DTO (Data Transfer Object).
For example, let’s say we have a custom object in our app called Settings
. Rather than just store settings data as a plain array on our Livewire component, we can attach associated behavior to this data with a convenient wrapper object or DTO like Settings
:
1class Settings implements Livewire\Wireable
2{
3 public $items = [];
4
5 public function __construct($items)
6 {
7 $this->items = $items;
8 }
9
10 ...
11
12 public function toLivewire()
13 {
14 return $this->items;
15 }
16
17 public static function fromLivewire($value)
18 {
19 return new static($value);
20 }
21}
Now you can freely use this object as a public property of your component as long as that object implements the Livewire\Wireable
interface AND the property is typehinted like so:
1class SettingsComponent extends Livewire\Component
2{
3 public Settings $settings;
4
5 public function mount()
6 {
7 $this->settings = new Settings([
8 'foo' => 'bar',
9 ]);
10 }
11
12 public function changeSetting()
13 {
14 $this->settings->foo = 'baz';
15 }
16}
And as you can see, changes to the component are persisted between requests because, with Wireable
, Livewire knows how to “dehydrate” and “re-hydrate” this property on your component.
If words like “hydrate” or “dehydrate” in the context of Livewire are fuzzy for you, give this post a quick read.
Computed Properties
Livewire offers an API for accessing dynamic properties. This is especially helpful for deriving properties from the database or another persistent store like a cache.
1class ShowPost extends Component
2{
3 // Computed Property
4 public function getPostProperty()
5 {
6 return Post::find($this->postId);
7 }
Now, you can access $this->post
from either the component's class or Blade view:
1class ShowPost extends Component
2{
3 public $postId;
4
5 public function getPostProperty()
6 {
7 return Post::find($this->postId);
8 }
9
10 public function deletePost()
11 {
12 $this->post->delete();
13 }
14}
1<div>
2 <h1>{{ $this->post->title }}</h1>
3 ...
4 <button wire:click="deletePost">Delete Post</button>
5</div>
Computed properties are cached for an individual Livewire request lifecycle. Meaning, if you call `$this->post` 5 times in a component's blade view, it won't make a separate database query every time.
← Previous Topic Rendering Components
Next Topic → Actions