Laravel Blade是一个强大的模板引擎,可让开发人员在Laravel应用程序中创建动态和可重复使用的视图。刀片的关键特征之一是能够创建可重复使用的组合组件,这可以帮助加快前端开发。通过启用可重复使用的组件来提供一致的样式和行为,开发人员可以避免需要从头开始构造元素。相反,他们可以简单地利用已经存在的组件。
在本文中,我们将创建一个基本形式,向您展示刀片组件的一些好处和技术。
创建您的第一个组件
有两种类型的组件:基于类和匿名的组件。基于类的组件具有类和视图模板,而匿名组件仅具有视图模板。在大多数情况下,匿名组件就足够了,我只有在需要使用依赖注入时才倾向于使用基于类的组件。
php artisan make:component layouts.app --view
运行上述命令将创建我们的第一个组件,一个名为Resources/views/components/layouts/app.blade.php的布局文件。该文件将是应用程序的布局。
<!-- /resources/views/components/layouts/app.blade.php -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel Blade Components</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
{{ $slot }}
</body>
</html>
<!-- /resources/views/example.blade.php -->
<x-layouts.app>
Hello World!
</x-layouts.app>
{{ $slot }}
将渲染我们传递给它的任何东西。例如,通过Hello World!将在页面上渲染。插槽是使刀片组件可组合的原因。我们可以将组件传递给其他组件,甚至可以使用named slots!
创建一个表单
运行以下以创建我们的匿名索引组件
php artisan make:component form.index --view
通常,要将组件组合在一起,您必须具有一个表单组件,然后将其余的表单组件在文件夹中。
/resources/views/components/form.blade.php
/resources/views/components/form/group.blade.php
匿名索引组件允许您将组件分组在一起。
/resources/views/components/form/index.blade.php
/resources/views/components/form/group.blade.php
用法看起来像
<x-layouts.app>
<x-form>
<x-form.group>
Hello!
</xform.group>
</x-form>
</x-layouts.app>
<!-- /resources/views/components/form/index.blade.php -->
@props([
'method' => 'POST',
'action',
'hasFiles' => false,
])
<form
method="{{ $method !== 'GET' ? 'POST' : 'GET' }}"
action="{{ $action }}"
{!! $hasFiles ? 'enctype="multipart/form-data"' : '' !!}
{{ $attributes->except(['method', 'action']) }}
>
@csrf
@method($method)
{{ $slot }}
</form>
我们定义了要组件接受的道具。我们能够设置一些明智的默认值。大多数表单作为POST
的方法,因此我们将其设置为默认情况。当表单发送文件时,我们需要具有enctype属性。而不是每次使组件都添加此属性时,而不是在需要时输入。
我们要确保开发人员在使用此组件时通过操作通过操作,以便我们将操作设置为道具,但没有设置默认值。如果不通过诉讼,laravel如果我们不进行isset()
检查,则会丢下错误。
回音$attributes
允许我们传递我们需要的任何其他属性,而无需在道具中定义它们。
<x-form action="/users"></x-form>
<x-form :action="route('users.store')"></x-form>
<x-form method="GET"></x-form>
<x-form has-files></x-form>
<x-form class="border border-red-200"></x-form>
<x-form
:action="route('photos.store')"
has-files
class="p-5"
>
//
</x-form>
在上面的示例中,我们使用:action
属性。我们使用:前缀表示它是PHP表达式或变量。我们也可以做:action="$someRoute"
。如果它是一个硬编码或原始值,我们会像普通一样做action="/"
。
创建文本输入
使用输入时,我喜欢创建一个可以使用输入组件的组组件。该组将显示标签,帮助文本和任何错误。
php artisan make:component input.group --view
在这里,我们使用$attributes->class(['block'])
设置默认类。如果要通过类属性,则任何类都将与块合并。
我们使用@class()
进行有条件设置类。始终显示text-gray-700 inline-block mb-1
,在存在$error
时,text-red-500
仅合并到默认值中。
如果我们没有通过道具,则未定义,这就是为什么我们使用@isset($help)
和@isset($error)
检查它们是否设置的原因。我们还可以将道具设置为将null
作为其默认值并进行检查。
<!-- /resources/views/components/input/group.blade.php -->
@props([
'label',
'for',
'help',
'error',
])
<label
{{ $attributes }}
{{ $attributes->class(['block']) }}
for="{{ $for }}"
>
<span
@class([
'text-gray-700 inline-block mb-1',
'text-red-500' => isset($error)
])
>{{ $label ?? '' }}</span>
<div class="mt-1">
{{ $slot }}
</div>
@isset($help)
<p class="mt-2 text-sm text-gray-500" id="{{ $for }}">{{ $help }}</p>
@endif
@isset($error)
<div class="mt-1 text-red-500 text-sm">{{ $error }}</div>
@endif
</label>
接下来我们将创建一个文本输入
php artisan make:component input.text --view
此组件使用@aware()
。这允许儿童组成部分access data in the parent component。
<!-- /resources/views/components/input/text.blade.php -->
@aware([
'error',
])
@props([
'value',
'name',
'for',
])
<input
{{ $attributes->class([
'shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md',
'border-red-500' => $error
]) }}
@isset($name) name="{{ $name }}" @endif
type="text"
@isset($value) value="{{ $value }}" @endif
{{ $attributes }}
/>
创建按钮
最后,我们可以创建一个按钮来提交表格。我们将再次使用匿名索引组件。这是因为我不想直接访问该按钮,而是想在primary
,secondary
按钮中使用此组件。
php artisan make:component button.index --view
<!-- /resources/views/components/button/index.blade.php -->
@aware([
'type',
])
<button
type="{{ $type }}"
{{ $attributes->class([
'inline-flex items-center border font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2',
]) }}
>
{{ $slot }}
</button>
接下来,我们创建我们的primary
按钮。您可以看到我们正在使用primary
组件中的x-button
。
php artisan make:component button.primary --view
<!-- /resources/views/components/button/primary.blade.php -->
@props([
'type' => 'button',
])
<x-button
{{ $attributes->merge(['class' => 'border-transparent shadow-sm text-white bg-indigo-600 hover:bg-indigo-700']) }}>
{{ $slot }}
</x-button>
将x-button
组件分开意味着我们可以在多个位置重复使用它,即使是单独使用它。
将所有这些放在一起
现在,我们创建了我们的组件,我们可以开始一起使用它们。我们首先使用表单组件包装所有输入,在这种情况下,我们只需要通过路由作为操作。接下来,我们有几个输入组,这些输入组为标签,一个错误和错误。错误来自所有视图可用的validation error bag。传递给输入组插槽是输入。在此示例中,我们使用自动属性将旧值传递给值属性。最后,我们使用按钮提交表格。
<x-form :action="route('users.store')">
<x-input.group label="Email" for="email" :error="$errors->first('email')">
<x-input.email name="email" :value="old('email')" />
</x-input.group>
<x-input.group label="Password" for="password" :error="$errors->first('password')">
<x-input.password name="password" :value="old('password')" />
</x-input.group>
<x-button.primary>
Submit
</x-button.primary>
</x-form>
我们也可以将刀片组件与普通的HTML混合。
<x-form action="/photo" has-files>
<div class="p-3 border border-slate-200">
<x-input.group label="Password" for="photo" :error="$errors->first('photo')">
<input type="file" name="photo" />
</x-input.group>
<button>Submit</button>
</div>
</x-form>
奖励提示
{{-- Short attribute syntax... --}}
<x-input.text $name />
{{-- Is equivalent to... --}}
<x-input.text name="{{ $name }}" />
Named Slots-您可以通过给组件中的名称在组件中具有多个插槽。
<x-modal>
<x-slot:header>
Hello World!
</x-slot>
Some lovely content
<x-slot:footer>
Goodbye World!
</x-slot>
</x-modal>
您通过以下来实现这一目标
<!-- /resources/views/components/modal/index.blade.php -->
<div>
<header>
{{ $header }}
</header>
<main>
{{ $slot }}
</main>
<footer>
{{ $footer }}
</footer>
</div>