To create a class based component, you may use the make:component
Artisan command. To illustrate how to use components, we will create a simple Alert
component. The make:component
command will place the component in the App\View\Components
directory:
php artisan make:component Alert
Manually Registering Package Components: register your components in the boot
method of your package's service provider:
use Illuminate\Support\Facades\Blade;
* Bootstrap your package's services.
*/
public function boot()
{
Blade::component('package-alert', AlertComponent::class);
}
Displaying Components:To display a component, you may use a Blade component tag within one of your Blade templates. Blade component tags start with the string x-
followed by the kebab case name of the component class:
<x-alert/>
<x-user-profile/>
character to indicate directory nesting
<x-inputs.button/>
Passing Data To Components: You may pass data to Blade components using HTML attributes. Hard-coded, primitive values may be passed to the component using simple HTML attributes. PHP expressions and variables should be passed to the component via attributes that are prefixed with :
<x-alert type="error" :message="$message"/>
It is not necessary to pass the data to the view from the component's render
method:
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
/**
* The alert type.
* @var string
*/
public $type;
/**
* The alert message.
* @var string
*/
public $message;
/**
* Create the component instance.
* @param string $type
* @param string $message
* @return void
*/
public function __construct($type, $message)
{
$this->type = $type;
$this->message = $message;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|\Closure|string
*/
public function render()
{
return view('components.alert');
}
}
component is rendered,may be display the contents of component's public variables by echoing the variables by name:
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
Casing: Component constructor arguments should be specified using camelCase
, while kebab-case
/**
* Create the component instance.
*
* @param string $alertType
* @return void
*/
public function __construct($alertType)
{
$this->alertType = $alertType;
}
The $alertType argument may be provided like so:
<x-alert alert-type="danger" />
Component Methods: public variables being available to your component template, any public methods on the component may also be executed
/**
* Determine if the given option is the current selected option.
*
* @param string $option
* @return bool
*/
public function isSelected($option)
{
return $option === $this->selected;
}
<option {{ $isSelected($value) ? 'selected="selected"' : '' }} value="{{ $value }}">
{{ $label }}
</option>
Using Attributes & Slots Inside The Class:Blade components also allow you to access the component name, attributes, and slot inside the class's render method.
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|\Closure|string
*/
public function render()
{
return function (array $data) {
// $data['componentName'];
// $data['attributes'];
// $data['slot'];
return '<div>Component content</div>';
};
}
Additional Dependencies: component requires dependencies from Laravel's service container,may list them before any of the component's data attributes and they will automatically be injected by the container:
use App\AlertCreator
/**
* Create the component instance.
*
* @param \App\AlertCreator $creator
* @param string $type
* @param string $message
* @return void
*/
public function __construct(AlertCreator $creator, $type, $message)
{
$this->creator = $creator;
$this->type = $type;
$this->message = $message;
}
Managing Attributes specify additional HTML attributes, such as class
, that are not part of the data required for a component to function
<x-alert type="error" :message="$message" class="mt-4"/>
All of the attributes that are not part of the component's constructor will automatically be added to the component's "attribute bag"
<div {{ $attributes }}>
<!-- Component Content -->
</div>
Default / Merged Attributes:merge additional values into some of the component's attributes
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>
If we assume this component is utilized like so:
<x-alert type="error" :message="$message" class="mb-4"/>
The final, rendered HTML of the component will appear like the following:
<div class="alert alert-error mb-4">
<!-- Contents of the $message variable -->
</div>
Filtering Attributes: filter attributes using the filter
method.
{{ $attributes->filter(fn ($value, $key) => $key == 'foo') }}
For convenience, you may use the whereStartsWith method to retrieve all attributes whose keys begin with a given string:
{{ $attributes->whereStartsWith('wire:model') }}
Using the first method, you may render the first attribute in a given attribute bag:
{{ $attributes->whereStartsWith('wire:model')->first() }}
Slots: Pass additional content to your component via "slots".
<div class="alert alert-danger">
{{ $slot }}
</div>
We may pass content to the slot by injecting content into the component:
<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
Scoped Slotswhich allow you to access data or methods from the component within your slot.
<x-alert>
<x-slot name="title">
{{ $component->formatAlert('Server Error') }}
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
Inline Component Views:For very small components, it may feel cumbersome to manage both the component class and the component's view template.
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|\Closure|string
*/
public function render()
{
return <<<'blade'
<div class="alert alert-danger">
{{ $slot }}
</div>
blade;
}
inline
option.
php artisan make:component Alert --inline
Anonymous Components :Components utilize a single view file and have no associated class. To define an anonymous component, you only need to place a Blade template within your resources/views/components
directory.
<x-alert/>
Data Properties / Attributes
<!-- /resources/views/components/alert.blade.php -->
@props(['type' => 'info', 'message'])
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>