
Componentes
Los componentes y las ranuras brindan beneficios similares a las secciones y diseños; sin embargo, algunos pueden encontrar el modelo mental de componentes y ranuras más fácil de entender. Hay dos enfoques para escribir componentes: componentes basados en clases y componentes anónimos.
Para crear un componente basado en clases, puede usar el comando make:component
Artisan. Para ilustrar cómo utilizar los componentes, crearemos un componente Alert
simple. El comando make:component
colocará el componente en el directorio App\View\Components
:
php artisan make:component Alert
El comando make:component
también creará una plantilla de vista para el componente. La vista se colocará en el directorio resources/views/components
.
Registro manual de componentes del paquete
Al escribir componentes para su propia aplicación, los componentes se descubren automáticamente dentro del directorio app/View/Components
y el directorio resources/views/components
.
Sin embargo, si está creando un paquete que utiliza componentes Blade, necesitará registrar manualmente su clase de componente y su alias de etiqueta HTML. Por lo general, debe registrar sus componentes en el método boot
del proveedor de servicios de su paquete:
:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot()
{
Blade::component('package-alert', AlertComponent::class);
}
Una vez que su componente ha sido registrado, puede ser renderizado usando su alias de etiqueta:
<x-package-alert/>
Visualización de componentes
Para mostrar un componente, puede usar una etiqueta de componente Blade dentro de una de sus plantillas Blade. Las etiquetas de los componentes de la hoja comienzan con la cadena x-
seguida del nombre del caso de kebab de la clase de componente:
<x-alert/>
<x-user-profile/>
Si la clase de componente está anidada más profundamente dentro del directorio App\View\Components
, puede usar el carácter .
para indicar el anidamiento del directorio. Por ejemplo, si asumimos que un componente está ubicado en App\View\Components\Inputs\Button.php
, podemos representarlo así:
<x-inputs.button/>
Pasar datos a componentes
Puede pasar datos a componentes Blade mediante atributos HTML. Los valores primitivos codificados de forma rígida se pueden pasar al componente utilizando atributos HTML simples. Las expresiones y variables de PHP deben pasarse al componente a través de atributos que usan el carácter :
como prefijo:
<x-alert type="error" :message="$message"/>
Debe definir los datos requeridos del componente en su constructor de clases. Todas las propiedades públicas de un componente se pondrán automáticamente a disposición de la vista del componente. No es necesario pasar los datos a la vista desde el método render
del componente:
<?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');
}
}
Cuando se procesa su componente, puede mostrar el contenido de las variables públicas de su componente haciendo eco de las variables por nombre:
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
Carcasa
Los argumentos del constructor de componentes deben especificarse usando camelCase
, mientras que kebab-case
deben usarse al hacer referencia a los nombres de los argumentos en sus atributos HTML. Por ejemplo, dado el siguiente constructor de componentes:
/**
* Create the component instance.
*
* @param string $alertType
* @return void
*/
public function __construct($alertType)
{
$this->alertType=$alertType;
}
El argumento $alertType
se puede proporcionar así:
<x-alert alert-type="danger" />
Métodos de componentes
Además de que las variables públicas estén disponibles para la plantilla de su componente, también se puede ejecutar cualquier método público en el componente. Por ejemplo, imagine un componente que tiene un método isSelected
:
/**
* Determine if the given option is the current selected option.
*
* @param string $option
* @return bool
*/
public function isSelected($option)
{
return $option === $this->selected;
}
Puede ejecutar este método desde la plantilla de su componente invocando la variable que coincida con el nombre del método:
<option {{ $isSelected($value) ? 'selected="selected"' : '' }} value="{{ $value }}">
{{ $label }}
</option>
Uso de atributos & Ranuras dentro de la clase
Los componentes Blade también te permiten acceder al nombre del componente, los atributos y la ranura dentro del método de renderizado de la clase. Sin embargo, para acceder a estos datos, debe devolver un cierre del método render
de su componente. El cierre recibirá una matriz $data
como único argumento:
/**
* 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>';
};
}
El componentName
es igual al nombre usado en la etiqueta HTML después del prefijo x-
. Por lo tanto, componentName
de <x-alert />
será alert
. El elemento attributes
contendrá todos los atributos que estaban presentes en la etiqueta HTML. El elemento slot
es una instancia Illuminate\Support\HtmlString
con el contenido de la ranura del componente.
Dependencias adicionales
Si su componente requiere dependencias del contenedor de servicios de Laravel , puede enumerarlas antes de cualquiera de los atributos de datos del componente y el contenedor las inyectará automáticamente:
use App\Services\AlertCreator
/**
* Create the component instance.
*
* @param \App\Services\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;
}
Gestión de atributos
Ya hemos examinado cómo pasar atributos de datos a un componente; sin embargo, a veces es posible que deba especificar atributos HTML adicionales, como class
, que no forman parte de los datos necesarios para que un componente funcione. Normalmente, desea pasar estos atributos adicionales al elemento raíz de la plantilla de componente. Por ejemplo, imagine que queremos representar un componente alert
así:
<x-alert type="error" :message="$message" class="mt-4"/>
Todos los atributos que no forman parte del constructor del componente se agregarán automáticamente a la bolsa de atributos » del componente «. Esta bolsa de atributos se pone automáticamente a disposición del componente a través de la variable $attributes
. Todos los atributos se pueden representar dentro del componente repitiendo esta variable:
<div {{ $attributes }}>
<!-- Component Content -->
</div>
El uso de directivas como
@env
directamente en un componente no se admite en este momento.
Atributos predeterminados /combinados
En ocasiones, es posible que deba especificar valores predeterminados para los atributos o fusionar valores adicionales en algunos de los atributos del componente. Para lograr esto, puede utilizar el método de atributo bag merge
:
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>
Si asumimos que este componente se utiliza así:
<x-alert type="error" :message="$message" class="mb-4"/>
El HTML renderizado final del componente tendrá el siguiente aspecto:
<div class="alert alert-error mb-4">
<!-- Contents of the $message variable -->
</div>
Atributos de filtrado
Puede filtrar atributos utilizando el método filter
. Este método acepta un cierre que debe devolver true
si desea conservar el atributo en la bolsa de atributos:
{{ $attributes->filter(fn ($value, $key) => $key == 'foo') }}
Para mayor comodidad, puede utilizar el método whereStartsWith
para recuperar todos los atributos cuyas claves comienzan con una cadena determinada:
{{ $attributes->whereStartsWith('wire:model') }}
Con el método first
, puede representar el primer atributo en una bolsa de atributos determinada:
{{ $attributes->whereStartsWith('wire:model')->first() }}
Ranuras
A menudo, deberá pasar contenido adicional a su componente a través de » ranuras «. Imaginemos que un componente alert
que creamos tiene el siguiente marcado:
<!-- /resources/views/components/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
Podemos pasar contenido al slot
inyectando contenido en el componente:
<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
A veces, un componente puede necesitar renderizar múltiples ranuras diferentes en diferentes ubicaciones dentro del componente. Modifiquemos nuestro componente de alerta para permitir la inyección de un » título «:
<!-- /resources/views/components/alert.blade.php -->
<span class="alert-title">{{ $title }}</span>
<div class="alert alert-danger">
{{ $slot }}
</div>
Puede definir el contenido de la ranura nombrada usando la etiqueta x-slot
. Cualquier contenido que no esté dentro de una etiqueta x-slot
se pasará al componente en la variable $slot
:
<x-alert>
<x-slot name="title">
Server Error
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
Ranuras con ámbito
Si ha utilizado un marco de JavaScript como Vue, es posible que esté familiarizado con » ranuras con alcance «, que le permiten acceder a datos o métodos desde el componente dentro de su ranura. Puede lograr un comportamiento similar en Laravel definiendo métodos públicos o propiedades en su componente y accediendo al componente dentro de su ranura a través de la variable $component
:
<x-alert>
<x-slot name="title">
{{ $component->formatAlert('Server Error') }}
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
Vistas de componentes integradas
Para componentes muy pequeños, puede resultar complicado administrar tanto la clase de componente como la plantilla de vista del componente. Por este motivo, puede devolver el marcado del componente directamente desde el método render
:
/**
* 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;
}
Generación de componentes de vista en línea
Para crear un componente que muestre una vista en línea, puede usar la opción inline
al ejecutar el comando make:component
:
php artisan make:component Alert --inline
Componentes anónimos
Similar a los componentes en línea, los componentes anónimos proporcionan un mecanismo para administrar un componente a través de un solo archivo. Sin embargo, los componentes anónimos utilizan un archivo de vista única y no tienen una clase asociada. Para definir un componente anónimo, solo necesita colocar una plantilla Blade dentro de su directorio resources/views/components
. Por ejemplo, suponiendo que haya definido un componente en resources/views/components/alert.blade.php
:
<x-alert/>
Puede utilizar el carácter .
para indicar si un componente está anidado más profundamente dentro del directorio components
. Por ejemplo, suponiendo que el componente está definido en resources/views/components/inputs/button.blade.php
, puede representarlo así:
<x-inputs.button/>
Propiedades /atributos de datos
Dado que los componentes anónimos no tienen ninguna clase asociada, es posible que se pregunte cómo puede diferenciar qué datos deben pasarse al componente como variables y qué atributos deben colocarse en la bolsa de atributos del componente .
Puede especificar qué atributos deben considerarse variables de datos utilizando la directiva @props
en la parte superior de la plantilla Blade de su componente. Todos los demás atributos del componente estarán disponibles a través de la bolsa de atributos del componente. Si desea dar un valor predeterminado a una variable de datos, puede especificar el nombre de la variable como clave de matriz y el valor predeterminado como valor de matriz:
<!-- /resources/views/components/alert.blade.php -->
@props(['type' => 'info', 'message'])
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>
Componentes dinámicos
A veces puede que necesite renderizar un componente pero no saber qué componente debe renderizarse hasta el tiempo de ejecución. En esta situación, puede utilizar el componente dynamic-component
integrado de Laravel para representar el componente en función de un valor o variable de tiempo de ejecución:
<x-dynamic-component :component="$componentName" class="mt-4" />
Tomado de https://www.oulub.com/es-ES/Laravel/blade-components