Passing Attributes to Laravel Blade Components

Last updated 18th September, 2023

Laravel Blade is a powerful feature that allows us to create reusable UI components with dynamic behaviour. Using Blade, we can pass data from the parent component to the child component, making it easier to manage the state of our components.

To pass attributes to a Blade component, we can use the attributes property. This property allows us to pass any HTML attributes to the component. let's first go through the basics of Blade first.

Understanding Laravel Blade Components

Components are a great way to keep our code organized and reduce duplication. By separating our UI code into components, we can make it easier to maintain and update our application with minimal rework.

When we create a Blade component, we define a template for the component and any associated logic in a single file. We can then use that component throughout our application by referencing its name.

Here's an example of a simple Blade component:

<!-- resources/views/components/alert.blade.php -->

<div class="alert alert-{{ $type }}">
    {{ $slot }}
</div>

In this example, we've defined a component called alert that accepts a $type parameter and a $slot parameter. The $type parameter is used to set the CSS class of the alert, and the $slot parameter is used to define the content of the alert.

We can use this component in our views like this:

<x-alert type="success">
    Your changes have been saved.
</x-alert>

In this example, we're using the alert component and passing in a $type parameter of success and a $slot parameter of "Your changes have been saved."

By default, Laravel will look for Blade components in the resources/views/components directory. However, we can customize the location of our components by updating the view.paths configuration option in our config/app.php file.

Overall, Blade components are a powerful tool that can help us create reusable UI code in our Laravel applications. By encapsulating our UI code into components, we can keep our code organized and reduce duplication.

Passing Data To Components

If you're using a class based blade component, you can define arguments in the constructor of the class. These will then be made available to the component instance in the template.

Here's an example:

// app/View/Components/Alert.php

public function __construct(
    public string $type = 'success',
    public string $message = ''
)
{
    //
}

public function render()
{
    return view('components.alert');
}
<!-- resources/views/components/alert.blade.php -->

<div class="alert alert-{{ $type }}">
    {{ $message }}
</div>
<!-- resources/views/welcome.blade.php -->

<x-alert type="danger" message="Something went wrong." />

In the example above, we define an Alert component that takes two attributes: type and message. We then pass the type and message attributes to the component in the welcome.blade.php view.

Working With Default Attributes

When working with Laravel Blade components, we can define default attributes that will be used if no value is passed to the component. This can save us time and reduce the amount of code we need to write.

To define default attributes for a component, we can use the $attributes property in the component class. This property should be an array that contains the default values for each attribute.

For example, let's say we have a component that displays a user's name and email address. We can define default values for these attributes like this:

class UserCard extends Component
{
    public $attributes = [
        'name' => 'John Doe',
        'email' => 'johndoe@example.com',
    ];

    public function render()
    {
        return view('components.user-card');
    }
}

Now, if we use this component without passing any values for the name and email attributes, the default values will be used:

<x-user-card />

This will render the following HTML:

<div>
    <h2>John Doe</h2>
    <p>johndoe@example.com</p>
</div>

We can also override the default values by passing new values to the component:

<x-user-card name="Jane Smith" email="janesmith@example.com" />

This will render the following HTML:

<div>
    <h2>Jane Smith</h2>
    <p>janesmith@example.com</p>
</div>

In summary, defining default attributes for Laravel Blade components can save us time and reduce the amount of code we need to write. We can define default values using the $attributes property in the component class, and these values will be used if no value is passed to the component.

Passing Attributes To Anonymous Components

If you create an anonymous blade component, you can still passing attributes through to the component. By default, Laravel will treat any data passed to the component that is not defined as a prop as an attribute.

@props([
    'style' => 'default',
    'width' => 'lg'
])

<section
    @class([
        'py-32 md:py-48 lg:py-64' => true,
        'bg-x-page' => $style === 'default',
        'bg-x-page-inverted' => $style === 'inverted',
        'bg-white' => $style === 'white'
    ])
    {{ $attributes }}
>
    {{ $slot }}
</section>

The above component is a section component I've used in a recent project. Using the @props directive, we instruct the component that style and width are data properties. This means that when you pass properties to the component, they will be injects as $style and $width variables on the instance. $attributes will contain any other properties.

<x-section class="mb-24" style="inverted" width="sm">
  <!-- Content -->
</x-section>

The class attribute, and any other properties defined will all end up in the attributes array. All you have to do to attach them to a HTML element is use {{ $attributes }} in your template.

Attribute Casting In Blade Components

When working with Laravel Blade Components, it is common to pass attributes to the component. In some cases, we may want to cast these attributes to a specific data type. This is where attribute casting comes in.

Attribute casting in Laravel Blade Components allows us to cast attributes to a specific data type. This can be useful when we want to ensure that the data being passed to the component is of the correct type.

To cast an attribute in a Blade Component, we can use the protected $casts property. This property should be an array where the keys are the attribute names and the values are the data types to cast the attributes to.

For example, let's say we have a User component that accepts a birthdate attribute. We want to ensure that the birthdate attribute is always a DateTime object. We can achieve this by adding the following code to our component:

protected $casts = [
    'birthdate' => 'datetime',
];

Now, whenever we pass a birthdate attribute to our User component, it will be automatically cast to a DateTime object.

It is important to note that attribute casting only works for attributes that are passed as strings. If an attribute is passed as an object or an array, it will not be cast.

In addition to casting to built-in data types like datetime, we can also define custom cast types. To do this, we need to define a cast class that implements the Castable interface. We can then use this cast class in the $casts property.

Overall, attribute casting in Laravel Blade Components is a powerful feature that allows us to ensure that the data being passed to our components is of the correct type. By using attribute casting, we can write more robust and reliable components.

Nested Components And Attribute Inheritance

When working with nested components, it's important to understand how attribute inheritance works. In Laravel Blade, attributes defined in the parent component are automatically inherited by child components. This means that any attributes defined in the parent component will be available in the child component without the need for explicit passing.

For example, let's say we have a parent component called card that defines a title attribute:

<x-card title="My Title">
    <x-slot name="body">
        <!-- child component here -->
    </x-slot>
</x-card>

In this example, the title attribute is defined in the card component. When we pass the body slot to a child component, the child component will automatically have access to the title attribute.

<!-- child component -->
<div class="card-body">
    <h5 class="card-title">{{ $title }}</h5>
    <p class="card-text">{{ $slot }}</p>
</div>

In this example, we're using the {{ $title }} variable to output the value of the title attribute that was defined in the parent component. This is possible because the title attribute is automatically inherited by the child component.

It's important to note that attribute inheritance only works for attributes that are defined in the parent component. If you define an attribute in the child component, it will not be automatically inherited by any nested components.

In addition to automatic attribute inheritance, you can also explicitly pass attributes from the parent component to a nested component using the attributes variable. This variable contains all of the attributes that were passed to the parent component, and can be passed along to any child components.

<x-card title="My Title" class="my-card-class">
    <x-slot name="body">
        <x-child-component :attributes="$attributes" />
    </x-slot>
</x-card>

In this example, we're passing the attributes variable to a child component using the :attributes="$attributes" syntax. This will pass all of the attributes that were defined in the parent component to the child component.

By understanding how attribute inheritance works in nested components, you can create more flexible and reusable component structures in your Laravel Blade applications.

Hope this helps 🤙

No comments yet…

DevInTheWild.

Login To Add Comments.

Want More Like This?

Subscribe to occasional updates.

Related Articles