Deep introduction about Laravel Livewire

Deep Dive Laravel Livewire

Livewire builds reactive and dynamic interfaces in Laravel using Blade and JavaScript. This is a full-stack Laravel framwork.

In this article, I am going to explain how to build simple livewire application and how it will be worked. We can use Livewire to implement the functionality like pagination, form validation and etc without page reload.

How does it work?

  • Livewire renders the initial component output with the page.
  • When an interaction happens, Livewire makes AJAX request to server with the updated data.
  • Server re-renders the component with updated HTML.
  • Livewire then intelligently mutates DOM according to the changes.

Prerequisites

  1. PHP 7.2.5 or higher
  2. Laravel 7.0 or higher

Installation

Install the package

composer require livewire/livewire

Include the Blade directives

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    @livewireStyles
</head>
<body>
    @livewireScripts
</body>
</html>

To activate Livewire on a page, we have to include @livewireStyles directory in the head tag and include @livewireScripts directory before the end body tag in the blade file.

Create Livewire component

Run the following command to create new Livewire component. For example Product. That will create Livewire component(app/Http/Livewire/Product.php) and blade file(resources/views/livewire/product.blade.php).

php artisan make:livewire Product

In this article, I am going to explain about Product model which has name and price with edit mode. Use below picture to understand

Livewire component:

class Product extends Component
{
    public $showModal = false;
    public $product;

    protected $rules = [
        'product.name' => 'required',
        'product.price' => 'required',
    ];

    public function render()
    {
        return view('livewire.product', ['products' => Product::all()]);
    }

    public function edit($productId)
    {
        $this->showModal = true;
        $this->product = Product::find($productId);
    }

    public function save()
    {
        $this->product->save();
        $this->showModal = false;
    }

    public function close()
    {
        $this->showModal = false;
    }
}

We can render Livewire component using @livewire('product')

Here, we have applied validation rules for coming data from view. I have written validation rules within $rules property

Blade file

<div class="card-body">
    <table class="table">
        <thead>
        <tr>
            <th>Name</th>
            <th>Price</th>
            <th></th>
        </tr>
        </thead>
        <tbody>
        @forelse ($products as $product)
            <tr>
                <td>{{ $product->name }}</td>
                <td>{{ $product->price }}</td>
                <td>
                    <a wire:click.prevent="edit({{ $product->id }})"
                       href="#" class="btn btn-sm btn-primary">Edit</a>
                </td>
            </tr>
        @empty
            <tr>
                <td colspan="3">No products found.</td>
            </tr>
        @endforelse
        </tbody>
    </table>

    <div class="modal" @if ($showModal) style="display:block" @endif>
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <form wire:submit.prevent="save">
                <div class="modal-header">
                    <h5 class="modal-title">Edit product</h5>
                    <button wire:click="close" type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    Name:
                    <br />
                    <input wire:model="product.name" class="form-control" />
                    Price:
                    <br />
                    <input wire:model="product.price" class="form-control" />
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-primary">Save changes</button>
                    <button wire:click="close" type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
                </form>
            </div>
        </div>
    </div>
</div>

wire:model="product.price" is used for binding a component with html input price.


Conclusion

Livewire full fills the gap between front-end and back-end. For more information, please visit official documentation:

Related articles

Signature Pad with Alpine.js

The post describes the implementation of signature pads with Alpine.js. It also discusses how to integrate it with laravel livewire.