Courses

Livewire 3 for Beginners with Laravel 12 Starter Kit

Multiple Components and Events

You're reading a FREE PREVIEW of a PREMIUM course.
Summary of this lesson:
- Setting up Livewire components for posts and comments
- Dispatching an event after saving a comment
- Listening to events in another Livewire component
- Updating the comment count dynamically

Video Version of the Lesson

[Only for premium members]

Link to the repository

[Only for premium members]

Text Version of the Lesson

There are a lot of cases where one Livewire component needs to communicate with another. In this lesson, let's see how it is done using Events.


Initial Components

In this example, we will have a Livewire component for showing a post and another component for posting a comment. When a comment is posted, the comment count in the ViewPost Livewire component should be updated.

event is triggered

DB structure: the Comment Model only has the post_id and body fields. And we need a comments() relationship in the Post Model.

database/migrations/xxxx_create_comments_table.php:

Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id');
$table->string('body');
$table->timestamps();
});

app/Models/Post.php:

use Illuminate\Database\Eloquent\Relations\HasMany;
 
class Post extends Model
{
protected $fillable = [
'title',
'body',
];
 
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
}

And here are the initial Livewire components.

app/Livewire/ViewPost.php:

use App\Models\Post;
use Illuminate\Contracts\View\View;
 
class ViewPost extends Component
{
public Post $post;
 
public int $commentsCount = 0;
 
public function mount(Post $post): void
{
$this->post = $post;
$this->post->loadCount('comments');
$this->commentsCount = $this->post->comments_count;
}
 
public function render(): View
{
return view('livewire.view-post');
}
}

resources/views/livewire/view-post.php:

<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 dark:text-gray-100">
 
<h1 class="text-lg font-bold mb-4">{{ $post->title }}</h1>
 
<p>Comments: {{ $commentsCount }}</p>
 
<livewire:create-comment :post="$post" />
</div>
</div>
</div>
</div>

app/Livewire/CreateComment.php:

use App\Models\Post;
use Livewire\Component;
use Livewire\Attributes\Validate;
use Illuminate\Contracts\View\View;
 
class CreateComment extends Component
{
public Post $post;
 
#[Validate('required')]
public string $body = '';
 
public function save(): void
{
$this->validate();
 
$this->post->comments()->create(['body' => $this->body]);
 
$this->reset('body');
}
 
public function render(): View
{
return view('livewire.create-comment');
}
}

Notice: As you can see in the CreateComment Livewire component, no mount() method exists. This is another alternative to reduce code. Livewire automatically sets $post to the correct Post from the Route Model Binding.

resources/views/livewire/create-comment.php:

<div class="mt-4">
<form method="POST" wire:submit="save">
<div>
<label for="body" class="block font-medium text-sm text-gray-700">Body</label>
<textarea id="body" wire:model="body" class="block mt-1 w-full border-gray-300 rounded-md shadow-sm"></textarea>
@error('body')
<span class="mt-2 text-sm text-red-600">{{ $message }}</span>
@enderror
</div>
 
<button class="mt-4 px-4 py-2 bg-gray-800 rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700">
Save
</button>
</form>
</div>

I will use it as a full-page Livewire component, so the Route would look like this.

routes/web.php:

Route::get('post/{post}', \App\Livewire\ViewPost::class);

After visiting the page, we have a...

The full lesson is only for Premium Members.
Want to access all 19 video+text lessons of this course? (1 h 04 min)

You also get:

  • 80 courses
  • Premium tutorials
  • Access to repositories
  • Private Discord