Laravel Volt

Laravel Volt

Written by Tony Lea on Jul 25th, 2023 ・ Views ・ Report Post

Laravel Volt is a new package that was announced during Laracon 2023. Volt brings the power of single file Livewire components to Laravel and it works seamlessly with Folio.

Similar to how React and Vue developers can write single-file components, Laravel Volt brings single-file components to blade templates. This will allow developers to create powerful and interactive components that leverage the back-end and the front-end.

Installation

To install Volt via composer, you can run the following command:

composer require livewire/livewire:^3.0@beta # Or ensure Livewire v3.x is installed...
composer require livewire/volt:^1.0@beta

These are currently using the beta versions, which will change when Volt and Livewire V3 are out of Beta.

Next, you will need to tell your application where to look for your single-file volt components. You can do this by running:

php artisan volt:install

This will install the Volt Service Provider in your application. Now that we are all setup, we can go ahead and create our first component.

Creating Components

You can easily create a new Volt Component by running:

php artisan make:volt counter

This will create a new file counter.blade.php in the resources/views/livewire directory, with the following contents:

<?php

use function Livewire\Volt\{state};

//

?>

<div>
    //
</div>

We can add a little bit of code to get our counter component working:

<?php

    use function Laravel\Volt\{state};
    state(['currentValue' => 0]);

    $increment = fn () => $this->currentValue++;
?>

<div> 
    <div>current Value: {{ $currentValue }}</div>
    <button class="mt-2" wire:click="increment">
        Increment
    </button>
</div>

Next, we can create a new Folio page to render our new component:

artisan make:folio volt

This will generate a new Folio page located at resources/views/pages/volt.blade.php. We can add the following code:

<x-layout>
    <div class="mt-6">
        <livewire:counter />
    <div>
</x-layout>

And, just as simple as that we have a simple counter component in our application.

volt counter example

Notice that this is not just a front-end counter. The variable $currentValue is a value stored in the back-end. This means that you can easily share data between your front-end and back-end with ease πŸŽ‰

Volt State

As you can see from above, Volt gives us the ability to easily manage state by utilizing the use function Laravel\Volt\{state}; declaration.

After defining the {state} declaration we now have access to the state helper function which we can use to set state for any of our variables:

<?php

    use function Laravel\Volt\{state};
    state(['currentValue' => 0]);

?>

Now, we will have access to the $currentValue variable inside of the template, and thanks to the power of Livewire and AlpineJS we can keep track of the state of any variables on the front-end and the back-end.

Locked State Properties

When creating a variable, or property, you may want to protect a variable from being tampered with on the client-side. You can do this with the locked() method, like so:

state(['id'])->locked();

Reactive State Properties

If your application has nested Livewire components and you want the data from nested components to update from parent to child or child to parent, you can do this by adding the reactive() method, like so:

state(['todos'])->reactive();

We can also create computed properties, which are variables that will be computed as the variable is fetched. Let's learn about those next.

Volt Computed Properties

Volt gives us an easy way of returning computed properties by utilizing the computed() function, here is an example of how we can accomplish this:

<?php

use App\Models\User;
use function Livewire\Volt\{computed, state};

state(['count' => 0]);

$totalUsers = computed(function(){
    return User::count();
});

?>

<div>
    {{ $this->totalUsers }}
</div>

As you'll see when we reference a computed property, we'll need to refer to the variable name by using the $this keyword, which references the computed value.

Volt Actions

Defining actions, or functions, in your Volt components is very easy. Here's an example of how we can create an action to add a new todo item in our database:

<?php
    use App\Models\Todo;
    use function Laravel\Volt\{state};
    
    state(['title' => '']);

    $add = function () {
        Todo:: create([
            'title' => $this-β€Ίtitle,
        ]);

        $this->title = ":
    };
?>

<div> 
    <form wire:submit.prevent="add"> 
        <input name="title" wire:model="title" />
        <button type="submit">Add Todo</button>
    </form>
</div>

In the code above when the form is submitted it will call the $add method and create the new todo in the database and clear out the title. Pretty cool 😎

Volt Validation Rules

You can also add validation to your Volt components really easily. Here's an example of how we can validate that the $title variable is not empty and has a minimum of at-least three characters.

<?php
    use App\Models\Todo;
    use function Laravel\Volt\{rules, state};
    
    state(['title' => '']);
    rules(['title' => 'required|min:3']);

    $add = function () {
        Todo:: create([
            'title' => $this-β€Ίtitle,
        ]);

        $this->title = ":
    };
?>

<div> 
    <form wire:submit.prevent="add"> 
        <input name="title" wire:model="title" />
        <button type="submit">Add Todo</button>
    </form>
    @error ('title')
        <span class="text-red-500">{{ $message }}</span>
    @enderror
</div>

You'll see that above we've added a new {rules} declaration that gives us access to the rules() helper method allowing us to add validation to any state in our volt component.

Conclustion

Be sure to learn more about Volt by visiting the official documentation at https://livewire.laravel.com/docs/volt.

Volt will help us build dynamic and interactive user interfaces without the need for separate files. Volt gives us code colocation, bringing the behavior and markup of components together in a single file for enhanced productivity. Electrifying stuff ⚑️

Comments (0)