wire:custom-event
وتقدر تلتقط هذا الحدث في Livewire باستخدام مستمع بالشكل:
@click="$dispatch('custom-event',{ name : '{{$note}}' })" wire:custom-event="logTest($event.detail.name);"
wire:custom-event
وتقدر تلتقط هذا الحدث في Livewire باستخدام مستمع بالشكل:
@click="$dispatch('custom-event',{ name : '{{$note}}' })" wire:custom-event="logTest($event.detail.name);"
To use a custom
AppServiceProvider -> boot
php artisan view:cache php artisan view:cache
عمل cache ل كل view
php artisan route:cache php artisan route:cache
انشاء cache لجميع routes في ملف bootstrap/cache/routes-*.php
php artisan event:cache php artisan event:cache
عمل كاش ل event and listeners في ملف bootstrap/cache/events.php
php artisan config:cache php artisan config:cache
يجمع جميع ملفات config/*.php في ملف واحد اسمو bootstrap/cache/config.php
php artisan optimize:clear php artisan optimize:clear
يمسح جميع ملفات الكاش php artisan config:clear php artisan route:clear php artisan event:clear php artisan view:clear
php artisan optimize php artisan optimize
يجمع عدة عمليات تحسين في امر واحد بتوليد الكاش
make:command
اذا بدي انشاء artisan مخصص يقوم بوظيفة معينة مثلا
vendor
يحتوي على جميع dependencies التي يثبتها composer
مثلا ثبتت livewire سوف يتم وضع الكود المصدري في Vendor
storage
يحتوي على جيمع logs وملفات الكاش
app -> اي ملفات ينشآها المشروع مثلا images framework -> كاش لارافيل نفسه logs -> سجلات التطبيق مثل الاخطاء او الاشعارات المعلومات
web.php
يحتوي على المسارات التي توفرها الجلسات sessions و ايضا عليه حماية من خلال CSRF
routes
يحتوي على تعريف جميع المسارات routes في المشروع
resources
تحتوي على blades
assets
يحتوي على كل assets - html - css - js - images - svg - icon في المشاريع الحديثة vite يضع المخرجات داخل public/build ويستدعيها من خلال @vite()
public
يحتوي على جذر المشروع الذي يستقبل كل الطلبات يستدعي Composer autoload يجب ان يكون index.php داخل public ممنوع يكون index.php داخل root directory لكي لا يتمكن احد من الوصول الي ملف .env
config
جميع ملفات اعدادات التطبيق
bootstrap
المرحلة التي ينشآ فيها laravel المشروع ويحتوي علي كل ملفات cache من خلال php artisan config:cache php artisan route:cache php artisan event:cache
app
الكود الاساسي للمشروع
php artisan up php artisan up
الخروج من وضع الصيانة
php artisan down --redirect=/ php artisan down --redirect=/
ينقل العميل على / route
php artisan down --with-secret php artisan down --with-secret
نفس الاشي ولاكن يقوم بانشاء key بنفسو
php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515" php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
اذا وضعت هاظ key بعد رابط الدومين بقدر اتخطى الصيانة وادخل على الموقع بسهولة
php artisan down --refresh=15 php artisan down --refresh=15
يطلب من المتصفح اعادة التحميل تلقائي كل ١٥ ثانية
php artisan down php artisan down
تعطيل الموقع للصيانة مثلا
php artisan config:publish2
نشر وتفعيل اي ملف config لم يتم نشره افتراضيا
php artisan config:cache
نجلب كل الملفات الي داخل مجلد Config ومنعمل الها cache
php artisan config:clear php artisan config:clear
مسح Config cache
$value = Config::get('app.timezone');4
انا عندي Directory Config هاظ المجلد داخلو جميع ملفات Config اذا بدي استدعي اي متغير من داخلهم بقدر استخدم Config::get('app.timezone')
php artisan env:decrypt php artisan env:decrypt
فك تشفير ملف .env يجب وضع key الذي تم انشائه اثناء عملية التشفير مهم اذا بدي ارفع ملف .env على github مثلا
php artisan env:encrypt php artisan env:encrypt
تشفير ملف .env وسوف يتم انشاء ملف .env.encrypted
env
اذا بدي استدعي اي متغير من .env
php artisan config:show database
اذا بدي اعرض Config ملف معين
php artisan about --only=environment
اذا بدي اعرض Config ل Section معين
php artisan about php artisan about
عرض نظرة شاملة كاملة عن كل Config
All of the configuration
جيمع Laravel Config موجدوة داخل مجلد Config وكل هذه موثقة جيدا في doc
throttle
debounce: يرسل الطلب بعد ما المستخدم يوقف كتابة لمدة X ms. إذا ظل يكتب، ما في طلب.
throttle: يرسل الطلب كحد أقصى مرّة كل X ms حتى لو المستخدم مستمر بالكتابة.
تستخدم throttle لما بدك تحديثات دورية أثناء الكتابة (مثلاً: حفظ تلقائي مستمر، معاينة فورية، بحث لحظي مع تتبّع).
<div wire:dirty wire:target="title">Unsaved...</div>
بظهر في حال كانت القيمة بتختلف عن قاعدة البيانات
wire:dirty.class="border-yellow"
في حال كان القيمة في الحقل غير القيمة في قاعدة البيانات بنفذ الستايل
public function updated($name, $value)
هاظ hook بستمع للواجهة ولما يتغير اي حقل برجع اسم الحقل و القيمة الجديدة وبنفذ الفنقشن بنفس الحظة التي تتغير فيها القيمة مباشرة
wire:model.blur="title"
يتم ربط القيمة وتحديثها عندما اخرج من الحقل
blur
ما يرسل Livewire أي تحديث للسيرفر إلا لما الحقل يفقد التركيز (blur) — يعني المستخدم ضغط Tab، أو نقر خارج الحقل. هذا يقلّل عدد الطلبات مقارنةً بـ .live أثناء الكتابة.
live
تحديث مباشر للقيم
wire:loading
يتم عرض العنصر اثناء عملية loading
protected function rules()
تمكنني من اني اعرف validation
$this->pull('title');
جلب القيمة ثم التفريغ للقيمة
$this->reset('title');
تفريغ القيمة
php artisan livewire:form PostForm
انشاء Form
class PostForm extends Form
انشاء الفورم الذي سوف يدير العمليات
@error('title') <span class="error">{{ $message }}</span> @enderror
عرض رسالة الخطا
$this->validate();
مهم لتشغيل validate اذا لم يتم اضافتو لا يعمل
#[Validate('required')]
يضيف validation و ايضا يتم عرض رسالة الخطا في نفس الفورم بشكل مرتب
<form wire:submit="save">
ارسال الفورم
$this->only(['title', 'content'])
جلب القيم
public $title = '';
تعريف العناصر التي سوف نستخدمها في form
Submitting a form
ارسال الفورم
if (! Auth::user()->isAdmin) {
طريقة ممتازة
if (! Auth::user()->isAdmin) {
هاي طريقة جيدة و فعالة
@if (Auth::user()->isAdmin())
هاي طريقة سيئة غير امنة لانو رح نقدر نستدعيها بسهولة
$this->authorize('delete', $post);
اهم اشي authorize عشان ما يقدر اي مخترق انو يحدف من الموقع لانو ممكن بسهولة يحذف اي منشور لانو قيم public بقدر استدعيها بسهولة بالمتصفح
Security concerns
زيادة الامان
$this->skipRender();
بمنع اعادة بناء الواجهة بشكل غير ثابت يعني ممكن حسب شرط معين ابني الواجهة او ما ابنيها
#[Renderless]
بمنع اعادة بناء الواجهة بشكل ثابت
Skipping re-renders
اذا كنت بدي امنع الواجهة تعيد البناء بشكل تلقائي
$event.target.value
في تطبيقات الويب، عندما تحدث أي تفاعل (مثل النقر، الضغط على زر، إدخال نص)، يقوم المتصفح بإنشاء كائن حدث (Event Object). هذا الكائن يحتوي على جميع المعلومات المتعلقة بالحدث، مثل:
نوع الحدث: هل هو نقرة، ضغط على زر، إرسال نموذج؟
العنصر المُشغّل (target): ما هو العنصر الذي تسبب في الحدث؟ (مثال: زر، حقل إدخال، رابط)
معلومات إضافية: مثل مفتاح لوحة المفاتيح الذي تم الضغط عليه، إحداثيات الماوس، إلخ.
Livewire يسمح لك بالوصول إلى هذا الكائن مباشرةً باستخدام المتغير $event.
$dispatch
اذا بدي ارسل حدث واستقبلو تم شرحها سابقا
$toggle('sortAsc')
بقدر بسهولة اغير قيمة اي متغير bool وتسمع في الواجهة بشكل مباشر بدون اي كود اضافة فقط اعرف المتغير
$refresh
هذه تعيد بناء الواجهة
$set('query', '')
هذه تمكنني اني اغير قيمة اي متغير
$parent.removePost
من خلال هذه استطيع استدعاء الي function من الاب وعرضه
Magic actions
هي أوامر جاهزة من Livewire تقدر تستدعيها مباشرة من Blade داخل مستمعات الأحداث
$this->js('onPostSaved');
بهده الطريقة نستطيع استدهاء الفنقشن الدي عرفناه في js داخل php
$wire.$js.bookmark()
بهذه الطريقة نستطيع استدعاء function التي عرفناها في js - في داخل alpine $wire.$js.bookmark()
wire:click="$js.bookmark"
هيك نستطيع ان نستدعي اي function الذي تم تعريفه في js
@script
نتمكن بهذه الطريقة نستطيع كتابة اكواد js داخل الملف php
$js('bookmark', () => {
هذه الطريقة نستطيع تعريف اي function ونستدعيه من خلال livewire
When you want to optimistically update the UI with JavaScript before making a server request
تفاؤل: تعدّل الواجهة فورًا، ثم ترسل طلب للسيرفر لتثبيت الحالة.
When you want to perform simple UI updates that don't require server communication
تحديثات واجهة خفيفة محليًا (بدون شبكة).
public function delete(Post $post)
بدل ما تستقبل ID وتعمل findOrFail، تقدر تخلي Livewire يجيب الموديل تلقائيًا إذا نوّهت النوع (type-hint):
x-on:trix-change="$wire.content = $event.target.value"
منقدر نسحب قيمة الحقل من خلال alpine من خلال $event.target.value $event الحدث target العنصر الي احنا في value القيمة الي داخلو وحسب الevent الي مستخدمينو منحدد متى مثلا نسحب القيمة او نعدلها
<span x-init="$el.innerHTML = await $wire.getPostCount()"></span>
اذا بدي استلم قيمة من livewire واعرضها مباشرة
ny parameters you pass to the $wire method will also be passed to the PHP class method. For example, consider the following Livewire action:
نستطيع تمرير القيم للسيرفر من خلال alpine بكل سهوله مثل المثال المرفق
incrementViewCount
PHP
لما تنادي $wire.someMethod() من Alpine، Livewire يرسل طلب شبكة للسيرفر ويشغّل ميثود PHP المقابل، ثم يعيد رندر المكوّن.
$wire
Livewire يوفّر لك كائن سحري في المتصفح اسمه $wire يمثل مكوّنك (خصائصه وميثوداته).
Livewire component is also an Alpine component
كل مكوّن Livewire هو أيضًا مكوّن Alpine “من تحت الغطاء”.
$this->authorize('delete', $post);
ضروري عشان الامان
Passing parameters
تمرير القيم
<span wire:loading>Saving...</span>
بظهر العنصر الي داخلو ما دام الفورم بعمل loading
window
اذا كان العنصر ليس داخل عنصر livewire ببساطة بضيف window عشان يستمع للحدث في كل الصفحة
dispatch
تقدر تطلق حدث مخصّص من Alpine باستخدام $dispatch('event-name', payload).
Listening for dispatched custom events
الاستماع للأحداث المخصّصة
Equivalent of calling .preventDefault()
امنع السلوك الافتراضي
Whatever text follows wire: will be used as the event name of the listener
أي حدث DOM: change, input, scroll, transitionend
<button type="button" x-on:click="$wire.$refresh()">...</button>
اذا بدي استخدمها مع alpinejs
When the $refresh action is triggered, Livewire will make a server-roundtrip and re-render your component without calling any methods.
بتعي بناء الواجهة
refresh
أي تغييرات محليّة (مثل wire:model المؤجَّلة) تُطبّق على السيرفر أولًا ثم يُعاد الرندر.
لن يُستدعى mount() مرة أخرى. لكنه سيعيد تنفيذ ما في render() وأي خواص محسوبة/استعلامات داخلها.
لا يجري validate() ولا أي منطق إضافي إلا إذا كتبته أنت.
Refreshing a component
أكشن جاهز من Livewire تستدعيه مثل أي ميثود:
foo: 'bob'
هيك ممكن نعمل override
Properties defined in an x-data directive are available to all element children. Even ones inside other, nested x-data components.
جميع البيانات يتم توريثها للابناء
x-show="open"
اضهار او اخفاء العنصر
@click="
تنفيد اي كود js عند الضغط
x-data="{ open: false }
تعريف بيانات محلية علي مستوى DIV
false
بيمنع ارسال request يعني بصير طلب محلي
$wire.set('todo', '')
بيرسل ايضا request للسيرفر
<button x-on:click="$wire.todo = ''">Clear</button>
هذا يغيّر القيمة في المتصفح فقط (state المحليّة).
لا يرسل طلب للسيرفر الآن.
عند أول جولة لاحقة (أي اكشن Livewire أو submit…)، Livewire يزامن القيمة الجديدة مع السيرفر.
المفيد: تفاعل لحظي بدون شبكة.
Manipulating properties
طرق للتعديل من JS
Todo character length: <h2 x-text="$wire.todo.length"></h2>
الحقل مربوط بـ wire:model="todo"، فـ Livewire يبقي قيمة todo محدثة محليًا في المتصفح.
عندما تكتب، تتغيّر $wire.todo فورًا في المتصفح؛ لذلك x-text="$wire.todo.length" تظهر الطول مباشرة بدون أي request.
Livewire exposes a magic $wire object to Alpine. You can access the $wire object from any Alpine expression inside your Livewire component.
داخل أي مكوّن Livewire، عندك كائن سحري اسمه $wire متاح في Alpine.
$wire هو “نسخة جافاسكربت” من المكوّن: فيه نفس الخصائص والميثودز، لكن القراءة منه لا تُرسل طلبًا للسيرفر.
Supported PHP types:
انواع ثانية مدعومة
Array, String, Integer, Float, Boolean, and Null.
اول اشي livewire بحول القيم الي json قبل ارسالها في request وبعد وصولها الي class يحولها الي قيم صريحة التي حددناها و هذه القيم محدودة لان json لا يستطيع حمل كل انواع البيانات
Supported property types
القيم المدعومة
$this->todos[] = $this->pull('todo');
بهاي الدالة يمكننا اخذ القيمة و بعد اخدها حذفها ونمرر لها نص باسم المتغير الذي نريد قيمته و يتعرف livewire تلقائي علييه وجب ان يكون معرف و public
Pulling properties
سحب وافراغ القيم في خطوة واحدة
reset
نستخدم هذه الدالة لتفريغ اي متغير
Resetting properties
تفريف المتغيرات
wire:click="add"
الامر الذي سوف يقوم بنقل البيانات وتفعيل الميثود في. class
wire:model="todo"
عملية الربط مهمة
public $todo = '';
اولا تعريف المتغير التي سوف تستقبل البيانات
wire:model
نقوم باضافة هذه التاق علي field الذي سوف يحتوي علي البيانات وسوف يقوم بنقل البيانات عند حدوث عملية submit or save وتنتقل البيانات الي الميثود المربوطة به
Data binding
تمرير البيانات من الواجهة الي class
Bulk assignment
تعيين جماعي للقيم
within your component's mount()
يمكنك تهيئة العناصر داخل mount method
Initializing properties
تهيئة العناصر
public Post $post;
او مباشرة من خلال تطابق الاسماء
public function mount(Post $post)
اولا من خلال mount
Using route model binding
طرق استلام البيانات
public function mount($id)
هنا يتم استقبال البيانات التي بعثت في route
Route::get('/posts/{id}', ShowPost::class);
من هنا بمرر البيانات
Accessing route parameters
تمرير بيانات من route
Setting additional layout file slots
اذا مثلا بدي اعمل @yield('style') بستخدم هاي الطريقة اول اشي لازم اني اعرف في layout ->. {{$style ?? ''}} بعدها لازم اني اروح علي component واضيف
<x-slot:syle>css<x-slost/>
->title('Create Post');
وهاي الطريقة الثانية من داخل render
#[Title('Create Post')]
الطريقة الاولى اني اضيف هاي الكود
Setting the page title
اذا بدي اغير title
->section('body');
برضو مهمة في حال كان اسم @yield ليس content بتضيف الاسم المخصص هنا
->extends('layouts.app');
مهمة جدا اذا انا بنيت layout مخصص واستخدمت في @yield لازم استخدم معو extends
#[Layout]
اذا بدي component معينة اعرضها في layout مختلف بضيف هاي فوق render
استخدم Attribute لما يكون الياوت ثابت وما تحتاج تمرير بيانات متغيّرة
Global layout configuration
كيفية تغيير layout الاساسي
Route::get('/posts/create', CreatePost::class);
هاي الطريقة عشان استدعي Component في Routes
Full-page components
استدعاء component ك صفحة كاملة
mount()
تحديث لاحق للمدخلات لا يعيد استدعاء mount()
mount()
أي قيمة تمرّرها في وسم المكوّن تُحقن في mount() كـ بارامترات: يعني البيانات بتنتقل نم باراميتر من ثم الي mount من ثم بتقدر تضيف عليها اي تعديلات ثم بتتخزن داخل public value
<livewire:create-post :title="$initialTitle" />
في حال كانت البيانات php يجب وضع نقطتين :
<livewire:create-post title="Initial Title" />
في حال كانت بيانات ثابتة بدون :
Passing data into components
تمرير البيانات الي components في حالتين
There are two ways to render a Livewire component on a page:
يمكن استدعاء component بطريقتين ١-من خلال استدعائها داخل صفحة ٢-من خلال جعلها صفحة كامل
<livewire:editor-posts.create-post />
وهيك اذا كانت داخل dir
<livewire:create-post />
هيك يتم استدعاء اي component
public function save()
يتم تشغيل هاي الفنقشن ك event مثلا في الفورم wire:submit="save" في هاي الحالة يتم تشغيل الفنقشن save
"Why isn't my component live updating as I type?" .prose .lw-tip pre:last-child { margin-bottom: 0px; }
إذا كتبت في الحقل وما شفت القيمة تتحدّث فورًا في الواجهة، هذا طبيعي في Livewire (v4).
Livewire صار يحدّث المكوّن فقط عند حدوث “Action” (زي ضغط زر submit أو wire:click) — مش مع كل ضغطة زر أثناء الكتابة.
الهدف: تقليل عدد الطلبات للسيرفر وتحسين الأداء.
لو بدك تحديث لحظي وأنت بتكتب، استخدم wire:model.live بدل wire:model.
Binding inputs to properties
تربط الحقل بالخاصية $title لكن في v4 لا يُرسل التحديث للسيرفر أثناء الكتابة.
Livewire يؤجّل الإرسال لغاية ما يصير Action (زي wire:click, submit …). هذا لتقليل الطلبات وتحسين الأداء.
wire:model="title"
تربط الحقل بالخاصية $title لكن في v4 لا يُرسل التحديث للسيرفر أثناء الكتابة.
Livewire يؤجّل الإرسال لغاية ما يصير Action (زي wire:click, submit …). هذا لتقليل الطلبات وتحسين الأداء.
:key="$post->id"
هاي ضرورية لما بدك تعمل loop وداخلو بدك تدخل Component لازم تضيف هاي الخاصية عشان livewire تقدر تطابق البيانات مع بعض
:$post
اختصار ل 'post' => $post
وهو تمرير بيانات ل كمبوننت يمكن استلام البيانات استلام البيانات اما من خلال mount($post) or public Post $post;
Adding wire:key to @foreach loops
مهمة جدا اي بيانات بدك تعمل عليها loop لازم توضعها داخل root وتعطي الخاصية wire:key='' ولازم يكون فريد عشان ال livewire يطابق العناصرمع بعض
with()
تستخدم لتمرير البيانات الي الواجهة لانو احيانا public مش مناسبة لجميع السيناريوهات لانها بتخضع ل حماية و تعامل مختلف فيمكنك استخدام with
Livewire components have properties that store data and can be easily accessed within the component's class and Blade view. This section discusses the basics of adding a property to a component and using it in your application.
يتكم الجزء اني بقدر اعمل متغيرات داخل Class تكون public واستدعيها في blade مثل ما يوضح في الصورة
Customizing component stubs
لما تعمل صفحة جديدة بكون في ملفات افتراضية يتم انشائها اذا بدي اخصص الملف اول ما اعملو شو يكون داخلو بنفذ الكوماند المرفق وبعدل ببساطة الملفات الافتراضية لانشاء الملفات
Omitting the render method
اذا حذفت render function تلقائيا livewire رح تبحث علي اول view يتطابق اسمه مع اسم Control وتبعثو للواجهة
php artisan make:livewire CreatePost --inline
لما تعمل Component بضمن html داخل نفس Class يعني بنشاء ملف واحد في App/Livewire وما بعمل ملف داخل view
->layout()
نستطيع من خلالها تحديد اي layout نريد تمرير البيانات له
return view('livewire.posts.index') ->layout('components.layouts.app', ['title' => 'Latest Posts']); // تمُرِّر بيانات للّياوت أيضًا
php artisan make:livewire CreatePost
كوماند مخصص لانشاء Component ينتج عن تنفيد هذا الكوماند ملفين
CLASS: app/Livewire/Counter.php المنطق VIEW: resources/views/livewire/counter.blade.php الواجهة
sub-directory
اذا بدي اعمل الملفات داخل مجلد
.hover
بيقوم بتحميل الصفحة اول ما تعمل تمرر الماوس على الرابط
wire:navigate
**يمنع اعادة التحميل الكاملة للصفحة يجلب الصفحة من خلال ajax بيبدل المحتوى القديم بالجديد بشكل يشبه Single Page Application **