Componentes Laravel 7
Published: 2020-05-05 01:54:50

Hola gente!  Hace tiempo que realizo apuntes para uso personal y estos últimos días llegue a la conclusión de que quizás pueden ser de utilidad para la comunidad, así que les comparto mis apuntes sobre Componentes en Laravel 7. 


Vamos a lo importante...

###¿Cómo creamos un componente?

```
php artisan make:component Product
```

Este comando creará dos archivos:

1. *Product.php* (resources/views)
2. *product.blade.php* (app/View/Components)

*Product.php* es una clase de php que contiene dos metodos, el metodo __construct() y el método render(), este último se va a encargar de retornar la vista asociada al componente (product.blade.php).

###¿Que  vamos a hacer en esta clase de php? 

Muy sencillo! Vamos a definir los atributos que sean necesarios para la utilización de nuestro componente y así darle dinamismo.
En este caso vamos a crear un componente para un producto simple.

``` 
class Product extends Component
{
   public $price;
   public $name;
   public function __construct($price,$name)
   {
       $this->price = $price;
       $this->name  = $name;
   }
   public function render()
   {
       return view('components.product');
   }
}

```

Ahora bien a simple vista no es algo nuevo, es algo a lo que estamos acostumbrados hacer. Pero no termina acá.
Nos vamos a dirigir  al archivo product.blade.php que nos creó laravel cuando ejecutamos el comando anteriormente mencionado.

*product.blade.php*:

```
<div>
 //Contenido del componente
</div>
```

Este es nuestro componente, la verdad que no tiene nada impresionante pero dentro de él podemos maquetar  todo lo que se nos antoje.

###¿Cómo lo hacemos dinámico?

Laravel nos permite que dentro del componente podemos acceder a los atributos que definimos anteriormente en la clase php de una manera global sin tener que pasarlos por el método **render()**.

 ```
<div>
   <h6>{{$name}}</h6>
 
   <p><strong>{{$price}}</strong></p>
</div>
```
De esta forma accedemos al atributo **$name** y **$price** de la clase *Product.php* que a la hora de crear una instancia de la misma podrá almacenar los valores que deseemos.

###¿Cómo utilizamos el componente en la vista?

La idea del componente es que pueda ser utilizado en cualquier momento de manera rápida y sencilla  por eso es que Laravel nos deja instanciar componentes en cualquier vista.
Supongamos que tenemos una vista *home.blade.php* y queremos incluir un producto destacado utilizando componentes.

 ```
<x-product/>
 ```
Con esa sintaxis tenemos nuestro componente instanciado en la vista home, pegando por así decirlo todo el html y la lógica que creamos en *product.blade.php*.


###¿Cuando le paso los atributos?

Para pasarle los atributos que creamos en la clase *Product.php* debemos recurrir a la sintaxis clásica de html.

```
 <x-product price="$2350" name="Car"   />
 <x-product price="$400"  name="Candy" />
```

De esta forma creamos una instancia del  componente product haciendo uso de los atributos declarados en la clase *Product.php*.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7fc0rsm0mg3v1ceg9525.png)

###¿Como le agrego estilos?

Seria lo mas lógico que nuestro componente lleve estilos definidos en un archivo CSS, para eso normalmente le aplicamos clases a nuestros elementos, en este ejemplo usaremos algunas clases de la librería Bootstrap:

```
 <x-product class="mr-3 bg-white" price="$2350" name="Car" />
```

Como vemos en la imagen no se aplica ningún cambio:

![Image2](https://dev-to-uploads.s3.amazonaws.com/i/tbveugri47e7w3g62rqh.png)

Por defecto Laravel a todos los atributos que son externos al constructor del componente los aloja en una variable **$attributes**, entonces si no colocamos dicha variable los cambios de nuestra clase de css nunca se verán reflejados, para eso es necesario que dentro de *product.blade.php*  la invoquemos:

```
<div {{$attributes}}> //Dentro de la primer tag del div
   <h6>{{$name}}</h6>
   <p><strong>{{$price}}</strong></p>
</div>
```

De esta manera nuestros atributos externos al constructor podrán ser utilizados con normalidad.

![Image3](https://dev-to-uploads.s3.amazonaws.com/i/wu3xdm8gtkir5q9x3kqb.png)

A este punto ya podremos implementar cualquier tipo de componente, solo queda a cargo de la imaginación de cada uno. Pero hay una cosa más que debemos saber...

###¿Que pasa si le queremos pasar variables como valor del atributo?

Supongamos que nuestro **$price** y **$name** son variables dentro de la vista donde instanciamos el componente,  si nos detenemos a pensarlo un segundo a simple vista no genera mucha complicación seria algo como esto:

```
<x-product price="{{ $price }}" name="{{ $name }}"/>
```
Es una solución totalmente válida pero podría generarnos problemas ya que al utilizar esta forma no le estamos diciendo a Laravel que el valor proviene de otra parte y podría verse de esta manera:

![Image4](https://dev-to-uploads.s3.amazonaws.com/i/21bblhjqz49kf7r611o3.png)

Por eso para evitar conflictos, Laravel nos recomienda a la hora de utilizar variables como valores de los atributos utilizar esta sintaxis:
```
<x-product :price="$price" :name="$name"/>
```

Con el “:” previo al atributo y eliminando las llaves le estamos diciendo a Laravel “Este valor viene de otro lado”.

###Conclusión:

Existen todavía aún más formas de agregar complejidad al componente pero difiere del fin del apunte que es mostrar el funcionamiento básico, de todas maneras podemos consultar estas formas en la documentación oficial de Laravel. 

Con todo esto dicho solo queda decir... “Manos a la obra”.  Si bien no abarcamos un ejemplo complejo, sirvió para explicar toda la lógica que lleva un componente y como evitar posibles anomalías. 

Muchas gracias!