#laravel #laravel-blade #laravel-7
#laravel #laravel-blade #laravel-7
Вопрос:
У меня есть некоторые часто используемые сложные элементы пользовательского интерфейса, созданные с помощью HTML (такие как карточки, группы кнопок и т.д.) Для этой цели я хотел бы создать повторно используемые элементы blade.
Самое близкое решение, которое я нашел, — это пользовательские директивы blade.
Я определил простую директиву card следующим образом:
Blade::directive('card', function ($expression) {
list($title, $icon, $buttons) = explode(',', str_replace(["'"], '', $expression));
$str = '<div class="card card-custom">
<div class="card-header">
<div class="card-title">
<span class="card-icon">
<i class="'.$icon.'"></i>
</span>
<h3 class="card-label">'.$title.'
</div>
<div class="card-toolbar">'.$buttons.'
</div>
</div>
<div class="card-body">';
return "<?php echo '".$str."'; ? >";
});
Blade::directive('endcard', function () {
return '</div></div>';
})
и в моем blade я просто называю это так:
@card('Dashboard', 'fa fa-tachometer', $buttonsHtml)
<div> Card content here...</div>
@endcard
Которые хотели бы прикрепленное изображение.
Проблема в том, что я не могу передать какой-либо параметр в качестве переменной (например, $ buttonsHtml), потому что он будет восприниматься буквально как «$ buttonsHtml».
Я не видел, чтобы кто-нибудь пытался оценить переменную перед передачей ее в пользовательскую директиву. Возможно ли это вообще?
Было бы бесполезно, если бы мне нужно было передать фактическое значение переменной $ buttonsHtml, поскольку оно генерируется какой-либо другой функцией. У кого-нибудь есть идея обойти или даже заменить использование пользовательских директив?
Ответ №1:
Вы можете использовать блочные компоненты для создания повторно используемых HTML-элементов, и поскольку ваш card
элемент довольно прост, я бы использовал анонимный компонент.
Создайте следующий файл:
«resources/views/components/card.blade.php «
@props([
'title' => '',
'icon' => '',
])
<div class="card card-custom">
<div class="card-header">
<div class="card-title">
<span class="card-icon"><i class="{{ $icon }}"></i></span>
<h3 class="card-label">{{ $title }}</h3>
</div>
@if(isset($toolbar))
<div class="card-toolbar">{{ $toolbar }}</div>
@endif
</div>
<div class="card-body">{{ $slot }}</div>
</div>
Теперь вы можете использовать его таким образом в своих файлах просмотра:
<!-- without toolbar -->
<x-card title="Dashboard" icon="fa fa-tachometer">
<div> Card content here...</div>
</x-card>
<!-- with toolbar -->
<x-card title="Dashboard" icon="fa fa-tachometer">
<x-slot name="toolbar">
{!! $buttonsHtml !!}
</x-slot>
<div> Card content here...</div>
</x-card>
Комментарии:
1. Большое вам спасибо за то, что приняли его для анонимного компонента.
Ответ №2:
В Laravel 7 представлены компоненты Blade. Это позволяет вам делать именно это. Смотрите здесь:https://laravel.com/docs/7.x/blade#components.
Эти компоненты могут вызываться с использованием HTML-подобных тегов, и вы можете передавать данные.
В вашем случае это может выглядеть следующим образом:
Именно так вы бы назвали свой компонент
<x-card title="Dashboard" icon="fa fa-tachometer">
<x-slot name="buttons">
Your buttons HTML here
</x-slot>
Card content here
</x-card>
resources/views/components/card.blade.php
<div class="card card-custom">
<div class="card-header">
<div class="card-title">
<span class="card-icon">
<i class="{{ $icon }}"></i>
</span>
<h3 class="card-label">{{ $title }}</h3>
</div>
<div class="card-toolbar">
{{ $buttons }}
</div>
</div>
<div class="card-body">
{{ $slot }}
</div>
</div>
app/View/Components/Card.php
class Card extends Component
{
/** @var string Card title */
public $title;
/** @var string Card icon */
public $icon;
public function __construct($title, $icon)
{
$this->title = $title;
$this->icon = $icon;
}
public function render()
{
return view('components.card');
}
}
Комментарии:
1. Большое вам спасибо, это был отличный ответ. Я выбрал другой ответ только для чуть меньшего количества кода, а это именно то, что я искал.
Ответ №3:
Это, безусловно, уникальный и интересный подход. Попробуйте записать это в кавычках без знака ‘$’, например :
`@card('Dashboard', 'fa fa-tachometer', 'buttonsHtml')
<div> Card content here...</div>
@endcard`
Это может сработать
Комментарии:
1. Спасибо, я на самом деле перепробовал так много вариантов передачи переменной, но безуспешно, я думаю, мне нужен более сложный подход к оценке.