December 28, 2020
One of the features present in the last few versions of Laravel is Blade components. For some reason (at least on the projects i had to to work) the adoption isn't great, and people simply don't know of what they are; probably because many times when learning a new Framework the main focus is like: where do i put the controllers/views/models... and thats about it.
Now with the introduction of JetStream (using the Livewire stack in particular), seems getting more attention since by default it's implemented using Components.
Re-usability, Right?. That's what 'components' are all about.
During the development of a backend app (with Laravel or any other framework), there are many occasions when we need to add certain pieces of logic that are going to be used in several places but there is not a real specification of how, or where to place them. I'm talking about code that escapes the MVC pattern, and how to link it to our frontend.
Some people approach this problem and throw some random classes on their app/ folder, others use 'Services', or even simple helpers(); and just embed the calls on each template (yuck!!)
But there is no a definitive way to do it, until now :)
So lets create one:
$ php artisan make:component Weather
# Creates:
# - app/View/Components/Weather.php
# - resources/views/components/weather.blade.php
And to use your new component, open any blade template of your app:
<x-weather />
Pretty simple: a Php file to put the logic and a template. Now, as i said before, you could just use the PHP class:
$ php artisan make:component Weather --inline
# Creates:
# - app/View/Components/Weather.php
Our you could also only create the Blade file and use it as a "HTML only" component.
$ vim resources/views/components/weather.blade.php
Like other frameworks that use components there is many stuff you can do to customize each instance.
Passing data using attributes:
<!-- Blade template -->
<x-weather range="daily" :location="$city" />
Note the difference on the notation when passing from a variable $location (that may come from the controller); or just a string we defining on the template itself (range=).
/* app/View/Components/Weather.php */
// ...
public function __construct($range, $location)
{
$this->range = $range;
$this->location = $location;
}
// ...
Another concept coming from other javascript-like frameworks like Vue, and you can use them to pass more complex data like HTML that may not fin using regular attributes.
<!-- somewhere on my views where we use our component -->
<x-weather>
<p>My slot data !!</p>
</x-weather>
And inside our Component's template we can use the $slot reference to use the content:
<!-- resources/views/components/weather.blade.php -->
<div>
<h2>My Weather Component</h2>
{{ $slot }}
</div>
You can use multiple named-slot as well:
<x-weather>
<x-slot name="city">
Montevideo
</x-slot>
<strong>Yes!</strong> Named/unnamed slots can be used
</x-weather>
And our Component ($city matches the x-slot name):
<!-- resources/views/components/weather.blade.php -->
<div>
<h2>My Weather Component: {{ $city }}</h2>
{{ $slot }}
</div>
This is all you need to start working with it, and you should! There is plenty of more features but these are the fundamentals.
Check the documentation for more details:
I'm a 32-years old programmer and web developer currently living in Montevideo, Uruguay. I been programming since I was about 15 y.o, and for the past 12 actively working in the area.