Компоненты Laravel предоставляют средства для извлечения некоторых частей веб-приложения в фрагменты многократного использования. В этом посте вы узнаете, как создавать блейд-компоненты в laravel 8+.
Если вы раньше работали с интерфейсными фреймворками, такими как Vuejs, вы, возможно, видели, как компоненты работают в таких фреймворках. Концепция компонентов в laravel такая же. Возможно, вы встречали компоненты laravel в предыдущих версиях Laravel, но у них было мало возможностей. С выпуском Laravel 8 компоненты получили больше возможностей, чем раньше. Сейчас компоненты предоставляют удобный способ написания более чистого кода.
В laravel есть 3 типа компонентов:
- Компоненты на основе классов.
- Анонимные компоненты.
- Встроенные компоненты.
Компоненты на основе классов
В подходе, основанном на компонентах, компонент имеет два файла: класс PHP, расположенный в каталоге App/View/Components , и файл представления, расположенный в каталоге resources/views/comComponents . Чтобы создать такой компонент, вы можете использовать команду artisan следующим образом:
php artisan make:component LatestPosts
После запуска этой команды вы увидите два созданных файла: app/View/Components/LatestPosts.php и resources/views/components/latest-posts.blade.php.
app/View/Components/LatestPosts.php
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class LatestPosts extends Component
{
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|string
*/
public function render()
{
return view('components.latest-posts');
}
}
resources/views/components/latest-posts.blade.php
<div>
latest posts will be displayed here
</div>
Чтобы отобразить компонент в шаблоне блейда, мы можем вызвать его, используя собственный синтаксис тега <x-{имя компонента}/>
. Например, чтобы отобразить компонент последних сообщений:
<x-latest-posts />
Теперь посмотрим, как передать данные компоненту. Представьте, что этот компонент отображает список сообщений, поступающих из базы данных. В нашем случае я просто добавлю простой массив для демонстрационных целей. Для этого вам необходимо определить данные как общедоступные свойства в классе компонента следующим образом:
class LatestPosts extends Component { public $latestPosts; public function __construct($latestPosts) { $this->latestPosts = $latestPosts; } }
Любое публичное свойство, определенное в классе компонента, доступное представлению, при условии, что вы внедрите эти свойства в конструктор, как показано выше.
Затем обновите тег определения компонента, чтобы разрешить принятие атрибута latePosts , используя синтаксис :latestPosts :
<x-latest-posts :latestPosts="$posts" />
Как видите, для отправки динамических данных имя атрибута должно начинаться с :
, затем имя атрибута. В этом примере я назначил переменную $posts для :latestPosts , поэтому нам нужно определить переменную $posts в контроллере, который отображает шаблон, предполагая HomeController .
HomeController.php
<?php namespace App\Http\Controllers; class HomeController extends Controller { public function index() { $posts = [ [ "title" => "What is Lorem Ipsum?", "content" => "orem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book" ], [ "title" => "Why do we use it?", "content" => "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English" ] ]; return view('welcome')->with('posts', $posts); } }
Обновите файл представления компонента LatestPosts следующим образом:
resources/views/components/latest-posts.blade.php
<div> @foreach($latestPosts as $post) <article> <h3>{{$post['title']}}</h3> <p>{{$post['content']}}</p> </article> @endforeach </div>
Теперь вы увидите публикации в браузере. Но вы можете спросить, можно ли передать данные в методе render()
компонента. Можно, и оно будет работать.
В дополнение к этому любой публичный метод, определенный в компоненте, также доступен в представлении(вьюхе) компонента. Например, давайте отформатируем содержимое приведенного выше фрагмента так, чтобы брать подстроку только из текста.
Добавьте метод в app/View/Components/LatestPosts.php.
Затем вызовите этот метод в представлении, используя метод как переменную, например:
в resources/views/comComponents/latest-posts.blade.php замените эту строку
<p>{{ $post['content'] }}</p>
на
<p>{{ $format($post['content']) }}</p>
Вложенные компоненты (Nesting)
Как и в случае с компонентами в Vuejs или Reactjs, если вы хотите вызвать компонент из родительского компонента, вы можете легко добиться этого и в компонентах laravel. Хорошим сценарием для этого является визуализация списка элементов, чтобы каждый элемент фактически был компонентом, отображающим один элемент.
Чтобы прояснить это, давайте создадим компонент для отображения только одного сообщения, поэтому в терминале запустите эту команду для создания компонента:
php artisan make:component Post
Теперь откройте класс компонента Post, который мы только что создали, и обновите его, как показано:
app/View/Components/Post.php
<?php namespace App\View\Components; use Illuminate\View\Component; class Post extends Component { public $post; public function __construct($post) { $this->post = $post; } public function format($content) { return substr($content, 0, 100) . "..."; } public function render() { return view('components.post'); } }
Как видите, я объявил свойство $post и внедрил его в конструктор. Переменная $post представляет один элемент сообщения. В реальном примере это представляет собой запись из базы данных.
Обновим resources/views/components/post.blade.php
<article> <h3>{{ $post['title'] }}</h3> <p>{{ $format($post['content']) }}</p> </article>
затем resources/views/components/latest-posts.blade.php
<div> @foreach($latestPosts as $post) <x-post :post="$post" /> @endforeach </div>
Как вы видите, я вызвал компонент так же, как и компонент последних сообщений, используя <x-post />, передав атрибут :post .
Обратите внимание, что я добавил метод format() в класс Post, поэтому вам придется удалить его из класса компонента LatestPosts, поскольку он там больше не нужен.
Если вы запустите этот код, вы увидите тот же результат, что и раньше.
Слоты компонентов
Еще одна приятная особенность компонента Laravel — слоты. Слот представляет собой раздел, который вы определяете в представлении компонента, и этот слот заполняется, когда вы вызываете этот компонент в шаблоне. Это то же самое, что ключевое слово @yield в шаблонах.
В предыдущем примере давайте добавим слот к компоненту LatestPosts , чтобы мы могли отображать заголовок страницы, то есть «Последние сообщения»:
resources/views/components/latest-posts.blade.php
<div> {{ $slot }} @foreach($latestPosts as $post) <x-post :post="$post" /> @endforeach {{ $pagination }} </div>
Чтобы указать слот в шаблоне, мы можем использовать тег <x-slot name=”name”> следующим образом:
<x-latest-posts :latestPosts="$posts"> <h2>Latest Posts</h2> <x-slot name="pagination"> <ul> <li><a href="#">1</a> </li> <li><a href="#">2</a> </li> <li><a href="#">3</a> </li> </ul> </x-slot> </x-latest-posts>
Поэтому я указал <x-slot name=”pagination”> и в компоненте напечатал имя слота ” $pagination ” как переменную. Обратите внимание, что переменная $slot по умолчанию по-прежнему используется для слота по умолчанию.
Анонимные компоненты
Анонимные компоненты — это такие компоненты, которые имеют только файл представления без класса. Эти компоненты размещаются в одном и том же представлении компонентов по адресу resources/views/comComponents . Чтобы передать атрибуты анонимным компонентам, вы должны указать их с помощью директивы @props в верхней части файла компонента.
Итак, если мы изменили компонент из предыдущего примера на анонимный компонент, мы должны сделать следующее:
resources/views/components/latest-posts.blade.php
@props(['latestPosts']) <div> @foreach($latestPosts as $post) <x-post :post="$post" /> @endforeach </div>
Затем вызовите компонент обычным способом:
<x-latest-posts :latestPosts="$posts"></x-latest-posts>
Директива @props принимает массив имен атрибутов.
Встроенные компоненты
Встроенные компоненты, используемые для простых компонентов. Со встроенными компонентами нет файла представления, а есть только класс, и метод рендеринга напрямую возвращает разметку компонента.
Чтобы сгенерировать встроенный компонент, укажите –inline
:
php artisan make:component MessageBox --inline
Пишем функцию render в MessageBox:
public function render() { return <<<'blade' <div class="message success"> {{ $slot }} </div> blade; }