Laravel 7 Class Based Components – Part I

Laravel 7 Class Based Components – Part I

Published: 8/7/20204 min read
Laravel
PHP

With Laravel 7.x we now have two new approaches or ways of writing our blade components: class based components and anonymous components. In this post I will focus on creating and including class based components as well as passing data to them.

Create

We can create components with an artisan command:

php artisan make:component Header

This will create two files: app/View/Components/Header.php and resources/views/components/header.blade.php.

Class

In the folder app/View/Components/ will now have a Header class that will help us in handling our component’s logic. The Header class will look like this:

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Header extends Component
{
    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.header');
    }
}

As you can see, our Header class has a render() function that renders our view. We will return to this class again after having a quick look at our view.

View

In the folder resources/views/components/ we will now have a header.blade.php blade file that will contain our blade view. header.blade.php will look like this:

<div>
    <!-- Well begun is half done. - Aristotle -->
</div>

Nothing but a div and an inspirational quote! 💪 . BTW, you can generate more of these amazing quotes by running:

php artisan inspire

Let’s add some hardcoded content to our header.blade.php so we can see it in action:

<div>
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Corporis, fuga.
</div>

Include

Including our component is a bit different from previous Laravel versions:

<x-header />

Example

Here is an example for creating and including a component with more than one word in its name.
Let’s create the component SpecialHeading:

php artisan make:component SpecialHeading

This will create two files: app/View/Components/SpecialHeading.php and resources/views/components/special-heading.blade.php.
And this is how you would include it:

<x-special-heading />

Passing Data

We pass data to components via attributes on the included component. However, because we are in a Class context, we should initialize our optional attributes with public class properties and assign our properties with the injected attribute data. So, let’s get back to our class and declare our public properties. Then, we will use our class constructor __construct() to assign our data:

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Header extends Component
{

    public $text; // Declare a public property

    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct($text)
    {
        // We expect a $text attribute from the component
        $this->text = $text;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.header');
    }
}

And this is how we are going to pass it as an attribute:

<x-header text="Hello World" />

In the blade file we created, display your data as you would normally do for blade template files:

<div>
    {{ $text }}
</div>

In this way, you can pass static chunks of data. Passing variables as data is similar to how you would to it in Vue.js:

@php
   $text = 'Hello World';
@endphp
<x-header :text="$text" />

A note about casing

There is a casing rule you should follow when working with class-based components. When you want to use a property/attribute name that has more than one word in it you need to camelCase it on the class context and kebab-case it on the component itself:

@php
   $text = 'Hello World';
@endphp
<x-header :just-another-text="$text" />

camelCase in the class:

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Header extends Component
{

    public $justAnotherText; // Declare a public property

    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct($justAnotherText)
    {
        // We expect a $justAnotherText attribute from the component
        $this->justAnotherText = $justAnotherText;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.header');
    }
}

At header.blade.php:

<div>
    {{ $justAnotherText }}
</div>

Creating components in a class context is very powerful and we haven’t even scratched the surface of all that is possible with this approach. You can manipulate data passed by attributes with class methods, inject dependencies to you class and much more. In the next part of this series I will go over methods and slots in class based components.
Read more about class-based components in the Laravel official docs:
👉 https://laravel.com/docs/7.x/blade#components