First look at Blade View Components in Laravel 7
Tags: laravel, php, webdev
Published: 2020-02-27 08:05:09

Components feature already existed in Laravel as Blade directives. [docs link](https://laravel.com/docs/6.x/blade#components-and-slots)
But, in Laravel 7, they just took it to a whole new level.
Let's dive in.
 
> Laravel 7 has not been released at the time of writing this article, if you want to follow along, you can download it with below command.

`laravel new projectname --dev`

##Creating Components
A new Artisan command is available to easily create components:

`php artisan make:component Alert`

This command will create two files:

* a class file (`App\View\Components\Alert.php`)
```php
<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert 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.alert');
    }
}
```
* a blade file (`resources/views/components/alert.blade.php`)
```html
<div>
    <!-- He who is contented is rich. - Laozi -->
</div>
```
Let's modify this HTML so that we can see this component in action when we render it.
```html
<div>
    <h3>Alert Component</h3>
</div>
```

##Rendering Components
Components are meant to be used within Blade templates. There is a special syntax to use a component in blade file.

> `x-` followed by the *kebab case* name of component class.

```html
<x-alert />
```
Let's use our `Alert` component in `welcome.blade.php`
```html
            <div class="content">
                <div class="title m-b-md">
                    Laravel
                </div>
                <div>
                    <x-alert/>
                </div>
            </div>
```
Output:
![Displaying Alert Component](https://dev-to-uploads.s3.amazonaws.com/i/m31nehaiy92lhn6ksepx.png)

##Automatic Discovery
Laravel can automatically discover components in `app/View/Components` directory and `resources/views/components` directory.

But what if components are nested in directories for example `App\View\Components\Alerts\Success.php` ?

> We can use `.` notation to indicate directory nesting.
```html
<x-alerts.success />
```
##Passing Data to Components
We can pass data via HTML attributes. It's similar to passing `props` in a Vue component.
* primitive or a hard coded value 
```html
<x-alert type="error" />
```
* variables and expressions should be passed with `:` prefix
```html
<x-alert :message="$message" />
```
In component's class, this data should be made available via constructor.
```php
class Alert extends Component
{
    public string $type;

    public string $message;

    public function __construct(string $type, string $message)
    {
        $this->type = $type;
        $this->message = $message;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.alert');
    }
}
```
Notice that both properties are set to `public`.
> All public properties will be available to component's view file. You don't need to pass the data to view from `render()` method.

`alert.blade.php` can use these properties as:
```html
<div>
    <div class="alert alert-{{$type}}">
        <h3>{{$message}}</h3>
    </div>
</div>
```
There are few other things related to this topic:
* Anonymous components
* Accessing public methods in view
but I think we can cover that in **Deeper look** article 🤷🏻‍♂️

> Calling it *First look* because I am actually reading docs while writing this article 😂 [docs link](https://laravel.com/docs/master/blade#components)

Let me know your thoughts about **Blade View Components** in comments below.