在 blade 中创建自定义 blade html 元素

Create custom blade html elements in blade

我有一些常用的复杂 UI 元素是用 HTML 构建的(例如卡片、按钮组等。) 为此,我想创建可重复使用的 blade 元素。

我找到的最接近的解决方案是自定义 blade 指令。

我定义了一个简单的卡片指令如下:

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 变量的实际值,那将毫无用处,因为它是由其他函数生成的。任何人都知道变通方法,甚至是使用自定义指令的替代方法吗?

这无疑是一种独特而有趣的方法。尝试在没有“$”符号的情况下将其写在引号中,例如:

`@card('Dashboard', 'fa fa-tachometer', 'buttonsHtml')
    <div> Card content here...</div>
@endcard`

可能有用

Laravel 7 引入了 Blade 个组件。它可以让你做到这一点。看这里:https://laravel.com/docs/7.x/blade#components.

可以使用 HTML-like 标签调用这些组件,您可以传递数据。

在你的情况下,这可能是这样的:

这就是您调用组件的方式

<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');
    }
}

您可以使用 Blade components to create reusable html elements and because your card element is pretty simple, I would use a anonymous component.

创建以下文件:

"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>