DEV Community

Cover image for Laravel: Blade Components 101
Eric The Coder
Eric The Coder

Posted on • Edited on

Laravel: Blade Components 101

Follow me!: Follow @EricTheCoder_



I publish regularly here on Dev.to, click follow if you want to miss nothing.

You can also follow me on Twitter: Follow @justericchapman

Blade components

Blade components are a subset of blade template that allow you to create new custom, reusable, encapsulated PHP and HTML.

For example you may want to create a navbar to be used in many of your application pages. So you build your navbar as a component and can reused the component wherever you want.

When created, component can be call with same syntax as any html tag:

<html>
    <body>
        <x-navbar/>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Class based component

Class based component is compose of a php file that encapsulate component logic and a template file.

To create a class based component you can use the Artisan command make:component

php artisan make:component Alert
Enter fullscreen mode Exit fullscreen mode

This command will create two files:

app\View\Components\Alert.php
resources\views\components\alert.blade.php
Enter fullscreen mode Exit fullscreen mode

The Alert.php file is a class that inherits from Component

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    public function __construct()
    {
        //
    }

    public function render()
    {
        return view('components.alert');
    }
}
Enter fullscreen mode Exit fullscreen mode

the alert.blade.php template file is an empty container:

<div>

</div>
Enter fullscreen mode Exit fullscreen mode

Let's do an example. The final goal will be to display a alert message and style that message base on the alert type (error or success)

When the component will be created you can call your new component by using the x-name syntax:

<x-alert type="error" :message="$message"/>
Enter fullscreen mode Exit fullscreen mode

The x- is a convention that tell Laravel to render the specified component name.

The ":" prefix in :message tell Laravel that the content of the props will be bind to a php expression/variables.

When you append the x- before the component name, Laravel know where to look to find your component.

:type and :message are data pass to the component

You can retreived those value in the component class file:

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    public $type;
    public $message;

    public function __construct($type, $message)
    {
        $this->type = $type;
        $this->message = $message;
    }

    public function render()
    {
        return view('components.alert');
    }
}
Enter fullscreen mode Exit fullscreen mode

Inside your component template, you may display the contents of your component's public variables by echoing the variables by name:

<div class="alert alert-{{ $type }}">
    {{ $message }}
</div>
Enter fullscreen mode Exit fullscreen mode

Component Attributes

Sometimes you may need to specify additional HTML attributes, such as class that are not part of your component data.

<x-alert type="error" :message="$message" class="mt-4"/>
Enter fullscreen mode Exit fullscreen mode

If you want to pass these additional attributes down to the root element of the component template you can use the $attributes variable.

<div {{ $attributes }}>

</div>
Enter fullscreen mode Exit fullscreen mode

That will render to:

<div class="mt-4">

</div>
Enter fullscreen mode Exit fullscreen mode

If a class attribute already exist in your div you can use $attributes->merge to merge both together.

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>
Enter fullscreen mode Exit fullscreen mode

That will render to:

<div class="alert alert-error mt-4">

</div>
Enter fullscreen mode Exit fullscreen mode

Slot

You will often need to pass additional content to your component via "slots". Component slots are rendered by echoing the $slot variable.

You can pass content to the component:

<x-alert>
    This is a alert
</x-alert>
Enter fullscreen mode Exit fullscreen mode

The slot content can now be use anywhere inside our component template:

<div class="alert alert-danger">
    {{ $slot }}
</div>
Enter fullscreen mode Exit fullscreen mode

You can pass multiple content (slot) by naming those:

<x-alert>
    <x-slot name="title">This is a alert</x-slot>
    <x-slot name="sub">This is a sub message</x-slot>
</x-alert>
Enter fullscreen mode Exit fullscreen mode

Those name slots contents can be use anywhere inside our component template:

<div>
    {{ $title }}
    {{ $sub }}
</div>
Enter fullscreen mode Exit fullscreen mode

Conclusion

That's it for today. Tomorrow the journey continue, if you want to learn more about component, read Laravel Official documentation: https://laravel.com/docs/8.x/blade#components
If you want to be sure to miss nothing click follow me here or on twitter!

Follow me!: Follow @EricTheCoder_


Top comments (5)

Collapse
 
alnahian2003 profile image
Al Nahian

That was a wholesome experience reading this article. Specially, I was reading the Laravel Blade Template's docs and got stuck at the Components part. So for more lucidity, I googled and found this article!

Thank You @ericchapman ๐Ÿฆ„

Collapse
 
esensats profile image
Yessen

This article is better than the docs since the docs provided me with <x-component:slotName> syntax which just won't work for no reason and didn't tell me why wouldn't it work and what other variants I have (name="slotName")

Collapse
 
paulpreibisch profile image
Paul Preibisch

This is an EXCELLENT article - indicates all the necessary hiddne bits to know about components. Thankyou!

Collapse
 
paulpreibisch profile image
Paul Preibisch

Thanks for the article,
By the way, I suggest to use Grammarly plugin, it will help with the grammar - :)

Collapse
 
gaweki profile image
Andrel Karunia S

hey, i have question, how to forward jquery or global variabel to the component?