Rendering Components
- Livewire Directive (
@livewire
) - Livewire Route Registration (
Route::livewire()
) - The Render Method (
render()
)
Livewire Directive (@livewire
)
The most basic way to render a Livewire component on a page is using the @livewire
blade directive:
1<div>2 @livewire('search-posts')3</div>
If you are on Laravel 7 or greater, you can use the tag syntax.
1<livewire:search-posts />
If you have a component inside of a sub-folder with its own namespace, you must use a dot (.
) prefixed with the namespace.
For example, if we have a SearchPosts
component inside of a app/Http/Livewire/Nav
folder, we would indicate it as such:
1namespace App\Http\Livewire\Nav;2 3use Livewire\Component;4 5class SearchPosts extends Component6{7 // ...8}
1<livewire:nav.search-posts />
Passing Initial Parameters
You can pass data into a component by passing additional parameters into the @livewire
directive. For example, let's say we have a ShowContact
Livewire component that needs to know which contact to show. Here's how you would pass in a contact
model.
1@livewire('show-contact', ['contact' => $contact])
If you are on Laravel 7 or greater, you can use the tag syntax.
1<livewire:show-contact :contact="$contact">
Now, you can intercept those parameters and store the data as public properties using the mount()
method/lifecycle hook.
mount()
instead of a class constructor (__construct()
) like you may be used to.
1use Livewire\Component; 2 3class ShowContact extends Component 4{ 5 public $name; 6 public $email; 7 8 public function mount($contact) 9 {10 $this->name = $contact->name;11 $this->email = $contact->email;12 }13 14 ...15}
Dependency Injection
Like a controller, you can inject dependencies by adding type-hinted parameters before passed-in ones.
1use Livewire\Component; 2use \Illuminate\Session\SessionManager 3 4class ShowContact extends Component 5{ 6 public $name; 7 public $email; 8 9 public function mount(SessionManager $session, $contact)10 {11 $session->put("contact.{$contact->id}.last_viewed", now());12 13 $this->name = $contact->name;14 $this->email = $contact->email;15 }16 17 ...18}
Accessing The Request
Because mount()
runs during the initial page load, it is the only place in a Livewire component you can reliably access Laravel's request object.
For example, you can set the initial value of a property based on a request parameter (possibly something passed in the query-string).
1use Livewire\Component; 2use \Illuminate\Session\SessionManager 3 4class ShowContact extends Component 5{ 6 public $name; 7 public $email; 8 9 public function mount($contact, $sectionHeading = '')10 {11 $this->name = $contact->name;12 $this->email = $contact->email;13 $this->sectionHeading = request('section_heading', $sectionHeading);14 }15 16 ...17}
Livewire Route Registration
If you find yourself writing controllers and views that only return a Livewire component, you might want to use Livewire's routing helper to cut out the extra boilerplate code. Take a look at the following example:
Before
1// Route 2Route::get('/home', 'HomeController@show'); 3 4// Controller 5class HomeController extends Controller 6{ 7 public function show() 8 { 9 return view('home');10 }11}12 13// View14@extends('layouts.app')15 16@section('content')17 @livewire('counter')18@endsection
After
1// Route2Route::livewire('/home', 'counter');
Note: for this feature to work, Livewire assumes you have a layout stored in resources/views/layouts/app.blade.php
that yields a "content" section (@yield('content')
)
Custom Layout
If you use a different layout file or section name, you can configure these in the standard way you configure laravel routes:
1// Customizing layout 2Route::livewire('/home', 'counter') 3 ->layout('layouts.base'); 4 5// Customizing section (@yield('body')) 6Route::livewire('/home', 'counter') 7 ->section('body'); 8 9// Passing parameters to the layout (Like native @extends('layouts.app', ['title' => 'foo']))10Route::livewire('/home', 'counter')11 ->layout('layouts.app', [12 'title' => 'foo'13 ]);
You can also configure these settings for an entire route group using the group option array syntax:
1Route::group(['layout' => 'layouts.base', 'section' => 'body'], function () {2 //3});
Or the fluent alternative:
1Route::layout('layouts.base')->section('body')->group(function () {2 //3});
Route Parameters
Often you need to access route parameters inside your controller methods. Because we are no longer using controllers, Livewire attempts to mimick this behavior through its mount
lifecycle hook. For example:
web.php
1Route::livewire('/contact/{id}', 'show-contact');
App\Http\Livewire\ShowContact.php
1use Livewire\Component; 2 3class ShowContact extends Component 4{ 5 public $name; 6 public $email; 7 8 public function mount($id) 9 {10 $contact = User::find($id);11 12 $this->name = $contact->name;13 $this->email = $contact->email;14 }15 16 ...17}
As you can see, the mount
method in a Livewire component is acting like a controller method would as far as its parameters go. If you visit /contact/123
, the $id
variable passed into the mount
method will contain the value 123
.
Route Model Binding
Like you would expect, Livewire components implement all functionality you're used to in your controllers including route model binding. For example:
web.php
1Route::livewire('/contact/{user}', 'show-contact');
App\Http\Livewire\ShowContact.php
1use Livewire\Component; 2 3class ShowContact extends Component 4{ 5 public $contact; 6 7 public function mount(User $user) 8 { 9 $this->contact = $user;10 }11}
Now, after visiting /contact/123
, the value passed into mount
will be an instance of the User
model with id 123
.
The Render Method
A Livewire component's render
method gets called on the initial page load AND every subsequent component update.
Returning Blade Views
The render()
method is expected to return a Blade view, therefore, you can compare it to writing a controller method. Here is an example:
1use Livewire\Component; 2 3class ShowPosts extends Component 4{ 5 public function render() 6 { 7 return view('livewire.show-posts', [ 8 'posts' => Post::all(), 9 ]);10 }11}
1<div>2 @foreach ($posts as $post)3 @include('includes.post', $post)4 @endforeach5</div>
Returning Template Strings
If your Livewire project uses Laravel 7 or above, you can optionally return a Blade template string from ->render()
.
1use Livewire\Component; 2 3class DeletePost extends Component 4{ 5 public $post; 6 7 public function mount(Post $post) 8 { 9 $this->post = $post;10 }11 12 public function delete()13 {14 $this->post->delete();15 }16 17 public function render()18 {19 return <<<'blade'20 <div>21 <button wire:click="delete">Delete Post</button>22 </div>23 blade;24 }25}
--inline
flag during creation: artisan make:livewire delete-post --inline