Blade Components
ایجاد کامپوننتهای قابل استفاده مجدد در Blade
Blade Components به شما امکان میدهند کامپوننتهای قابل استفاده مجدد ایجاد کنید که میتوانند در viewهای مختلف استفاده شوند. این الگو کد را modular و maintainable میکند.
انواع Blade Components:
1. Anonymous Components: کامپوننتهای بدون کلاس که فقط view file دارند. سادهتر و سریعتر برای کامپوننتهای ساده.
2. Class-based Components: کامپوننتهای مبتنی بر کلاس که logic و data manipulation دارند. برای کامپوننتهای پیچیدهتر.
مزایای Components:
- استفاده مجدد در چند view
- کد تمیزتر و organizedتر
- مدیریت بهتر UI elements
- Props برای passing data
- Slots برای dynamic content
- Attributes merging برای HTML attributes
- Event handling
- State management
ویژگیهای پیشرفته:
- <strong>Props</strong>: دریافت data از parent
- <strong>Slots</strong>: محتوای dynamic
- <strong>Named Slots</strong>: چند slot با نامهای مختلف
- <strong>Attributes</strong>: HTML attributes merging
- <strong>Events</strong>: Event handling
- <strong>Computed Properties</strong>: محاسبه properties
- <strong>Lifecycle Hooks</strong>: hooks برای component lifecycle
مثالها
Anonymous Component
<!-- resources/views/components/alert.blade.php -->
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
<!-- Usage -->
<x-alert type="error" message="Something went wrong!" />
<!-- With default props -->
<!-- In component -->
@props(['type' => 'info', 'message' => ''])
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
استفاده از یک کامپوننت anonymous با props.
Class-based Component
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
public function __construct(
public string $type = 'info',
public string $message = '',
public bool $dismissible = false
) {}
public function render()
{
return view('components.alert');
}
public function alertClass(): string
{
return match($this->type) {
'error' => 'alert-danger',
'success' => 'alert-success',
'warning' => 'alert-warning',
default => 'alert-info'
};
}
}
<!-- Usage -->
<x-alert type="error" message="Error occurred" :dismissible="true" />
ایجاد یک کامپوننت مبتنی بر کلاس.
Component با Slots
<!-- resources/views/components/card.blade.php -->
<div class="card">
@if(isset($header))
<div class="card-header">
{{ $header }}
</div>
@endif
<div class="card-body">
{{ $slot }}
</div>
@if(isset($footer))
<div class="card-footer">
{{ $footer }}
</div>
@endif
</div>
<!-- Usage -->
<x-card>
<x-slot name="header">
<h2>Card Title</h2>
</x-slot>
Card content here
<x-slot name="footer">
<button>Action</button>
</x-slot>
</x-card>
استفاده از slots برای dynamic content.
Attributes Merging
<!-- resources/views/components/button.blade.php -->
@props(['type' => 'button', 'variant' => 'primary'])
<button
type="{{ $type }}"
{{ $attributes->merge(['class' => 'btn btn-' . $variant]) }}
>
{{ $slot }}
</button>
<!-- Usage -->
<x-button variant="danger" class="custom-class" id="submit-btn">
Submit
</x-button>
<!-- Renders: -->
<!-- <button type="button" class="btn btn-danger custom-class" id="submit-btn">Submit</button> -->
Attributes merging برای HTML attributes.
Component با Data
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class UserList extends Component
{
public function __construct(
public $users,
public bool $showEmail = true
) {}
public function userCount(): int
{
return $this->users->count();
}
public function render()
{
return view('components.user-list');
}
}
<!-- Usage -->
<x-user-list :users="$users" :show-email="false" />
Component با data و computed properties.
Inline Components
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
public function __construct(
public string $type,
public string $message
) {}
public function render()
{
return <<<'blade'
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
blade;
}
}
Inline component که view file ندارد.
Component Namespaces
<?php
// In AppServiceProvider
use Illuminate\Support\Facades\Blade;
Blade::componentNamespace('App\View\Components\Forms', 'forms');
// Usage
<x-forms::input name="email" type="email" />
// Or in package
Blade::componentNamespace('Vendor\Package\View\Components', 'package');
// Usage
<x-package::component />
Component namespaces برای organization بهتر.
Dynamic Components
<!-- Dynamic component selection -->
<x-dynamic-component :component="$componentName" :data="$data" />
<!-- Example -->
@php
$componentName = 'alert';
$data = ['type' => 'error', 'message' => 'Error!'];
@endphp
<x-dynamic-component :component="$componentName" :type="$data['type']" :message="$data['message']" />
Dynamic component selection بر اساس variable.
موارد استفاده
- ایجاد reusable UI elements
- سازماندهی view code
- ایجاد design system components
- کاهش code duplication
- مدیریت complex UI logic
- ایجاد component library
اشتباهات رایج
- استفاده از class-based component برای simple components
- عدم استفاده از props که باعث hard-coding میشود
- فراموش کردن attributes merging
- قرار دادن business logic در component
- عدم استفاده از slots برای flexibility
- Component namespaces که باعث confusion میشود
بهترین روشها
- از anonymous components برای simple components استفاده کنید
- از class-based components برای complex logic استفاده کنید
- از props برای data passing استفاده کنید
- از slots برای dynamic content استفاده کنید
- از attributes merging برای HTML attributes استفاده کنید
- Component names را descriptive انتخاب کنید
- Components را test کنید
موارد خاص
- Nested components با complex data flow
- Components با conditional rendering
- Dynamic component selection
- Components با event handling
- Component caching در production
- Components با very large props
نکات عملکرد
- Anonymous components سریعتر از class-based هستند
- Component compilation cached میشود
- استفاده از inline components میتواند overhead داشته باشد
- Nested components میتوانند slow باشند
- Component caching در production بهبود performance میدهد
نکات امنیتی
- مطمئن شوید که props به درستی escaped میشوند
- از raw output در components با احتیاط استفاده کنید
- مطمئن شوید که user input در props validated میشود
- از component namespaces برای isolation استفاده کنید
نکات مصاحبه
- تفاوت بین anonymous و class-based component چیست؟
- Props چیست و چگونه کار میکند؟
- Slots چیست و چه زمانی استفاده میشود؟
- Attributes merging چگونه کار میکند؟
- چگونه میتوان component namespace تعریف کرد؟
- مزایای استفاده از Blade components چیست؟
یادداشتهای نسخه
- Laravel 11.x: بهبود performance در component rendering
- Laravel 11.x: پشتیبانی بهتر از attributes merging
- Laravel 10.x: بهبود anonymous components
- Laravel 9.x: بهبود component namespaces