Livewire چیست ؟ قسمت اول آموزش Livewire در لاراول

دسته بندی: لاراول
سطح مقاله: پیشرفته
زمان مطالعه: 30 دقیقه
۱۶ مهر ۱۳۹۹

با رونق گرفتن استفاده از وب اپلیکیشن‌های مدرن، وجود ابزارهایی به منظور هر چه ساده‌تر کردن فرآیند ساخت آن‌ها، امری ضروری تلقی می‌شود. ابزارهایی مانند Vue یا React، در این زمینه بسیار قدرتمند هستند، اما پیچیدگی‌ استفاده از آن‌ها برای یک توسعه دهنده‌ی فول استک، غیرقابل اجتناب است. در این مقاله قصد داریم به آموزش Livewire در لاراول بپردازیم. livewire چیست ؟ Livewire یک فریم‌ ورک فول استک برای لاراول است که ایجاد رابط‌های کاربری داینامیک را در وب اپلیکیشن‌های مدرن ساده کرده است.

اگر با داشتن دانش کافی در زمینه‌ی فریم ورک لاراول، نیاز دارید یک وب اپلیکیشن پویا را بدون استفاده از فریم‌ ورک‌های پیچیده‌ی جاوا اسکریپت مثل Vuejs ایجاد کنید، Livewire بهترین انتخاب شماست. این فریم ورک مخصوصا برای ایجاد Single Page Application یا SPA‌ها بسیار کاربردی است. با استفاده از Livewire، نیازی به نوشتن کدهای JQuery برای درخواست‌های Ajax وب اپلیکیشن خود نخواهید داشت و Livewire به شما کمک خواهد کرد که بدون نیاز به Refresh صفحه، عملیات مورد نظر خود را از قبیل اعتبارسنجی فرم، ثبت فرم، ذخیره فایل و ... انجام دهید.

در ادامه با ما همراه باشید تا یکی از بهترین فریم ورک‌های فول استک یعنی Livewire را برای ایجاد وب اپلیکیشن به شما آموزش دهیم.

فهرست محتوای این مقاله

نحوه‌ی کار Livewire

برای آن که بهتر درک کنیم Livewire چیست ، ابتدا باید نحوه‌ی کار Livewire در لاراول را بدانیم که به طور اجمالی در چهار بخش زیر خلاصه می‌شود:

  • ابتدا برای Livewire کامپوننت‌هایی را تعریف می‌کنیم که خروجی اولیه‌ی این کامپوننت‌ها مثل دستور include در blade، در صفحه رندر می‌شوند. به این صورت برای سئو هم مناسب و به عبارتی seo friendly است.

  • زمانی که تعاملی در صفحه رخ می‌دهد، Livewire یک درخواست Ajax را به همراه داده‌های جدید به سمت سرور ارسال می‌کند.

  • سرور کامپوننت‌ها را دوباره رندر می‌کند و ساختار HTML جدید را برای کاربر ارسال می‌کند.
  • سپس Livewire ساختار DOM را براساس داده‌های آپدیت شده و خروجی کامپوننت‌ها، به صورت هوشمند تغییر می‌دهد.

نیازمندی‌های اولیه

برای شروع کار، علاوه بر HTML و CSS، فقط به دانش کافی در زمینه‌ی لاراول نیاز دارید و بدون نیاز به جاوا اسکریپت می‌توانید وب اپلیکیشن پویای خود را ایجاد کنید.

تعریف پروژه

در این مقاله برای انتقال هرچه بهتر مطالب و این که Livewire چیست و چه کاربردی دارد، قصد داریم یک Single Page Application یا SPA را با هم ایجاد کنیم تا شما به صورت عملی با ویژگی‌ها و امکانات Livewire بیشتر آشنا شوید.

اپلیکیشن ما یک سری کاربر دارد که این کاربران پس از ورود، نظرات مختلف خود را راجع به یک تاپیک خاص ارسال می‌کنند و کل فرآیند ثبت نام، ورود و خروج و ارسال نظر بدون نیاز به Refresh صفحه انجام می‌شود.

راه‌اندازی پروژه

در این بخش نیاز دارید پروژه‌ی لاراول خود را راه‌اندازی کنید.

نصب لاراول

سپس به پوشه‌ی دلخواه خود بروید و دستور زیر را برای نصب لاراول اجرا کنید:

composer create-project --prefer-dist laravel/laravel blog

حالا با دستور زیر می‌توانید پروژه را اجرا کنید:

php artisan serve

پس از اجرای این دستور، پروژه بر روی پورت 8000 لوکال هاست به آدرس http://localhost:8000 در دسترس است که با وارد کردن آن در نوار آدرس مرورگر، با این صفحه مواجه می‌شوید:

Livewire چیست

نصب Livewire

با استفاده از دستور زیر Livewire را نصب کنید:

composer require livewire/livewire

ایجاد کامپوننت

دستور زیر را اجرا کنید و کامپوننت Comments را ایجاد نمایید:

php artisan make:livewire Comments

با اجرای این دستور، دو فایل در پروژه ایجاد می‌شوند. یک فایل در پوشه‌ی livewire در مسیر resources/views با نام Comments.blade.php برای نمایش نظرات و یک فایل در پوشه‌ی livewire در مسیر app/Http با نام Comments.php که کامپوننت نظرات ما را در برمی‌گیرد و در واقع از کلاس Component در هسته‌ی Livewire ارث‌بری می‌کند.

پس از پایان اجرای دستور ممکن است از شما خواسته شود که به مخزن گیت هاب Livewire ستاره اختصاص دهید که می‌توانید با وارد کردن No از انجام این مورد صرف‌نظر کنید.

ایجاد Viewها

برای قالب HTML صفحات، فایل welcome.blade.php که به صورت پیش فرض در مسیر resources/views وجود دارد را به شکل ساده شده‌ی زیر تغییر می‌دهیم. شما می‌توانید از هر صفحه‌ی دلخواه دیگری به عنوان صفحه‌ی اصلی وب اپلیکیشن خود استفاده کنید.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Livewire</title>
       <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
   <style>
      * {
         font-family: 'Nunito', monospace;
      }
   </style>
</head>

<body class="d-flex justify-content-center">
<div class="w-75 d-flex mt-5">
    <div class="w-100 mx-3 rounded border p-5">

    </div>
</div>

</body>

</html>

در مرحله‌ی بعد فایل‌های استایل و اسکریپت مربوط به Livewire و کامپوننت Comments را در این صفحه قرار دهید:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Livewire</title>
       <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    @livewireStyles

   <style>
      * {
         font-family: 'Nunito', monospace;
      }
   </style>
</head>

<body class="d-flex justify-content-center">
<div class="w-75 d-flex mt-5">
    <div class="w-100 mx-3 rounded border p-5">
        @livewire('comments')
    </div>
</div>

@livewireScripts
</body>

</html>

اگر از لاراول 7 یا بالاتر استفاده می‌کنید می‌توانید به شیوه‌ی زیر عمل کنید:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Livewire</title>
       <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    <livewire:styles />

   <style>
      * {
         font-family: 'Nunito', monospace;
      }
   </style>
</head>

<body class="d-flex justify-content-center">
<div class="w-75 d-flex mt-5">
    <div class="w-100 mx-3 rounded border p-5">
        <livewire:comments />
    </div>
</div>

<livewire:scripts />
</body>

</html>

برای بخش نظرات در فایل comments.blade.php در مسیر resources/views/livewire ساختاری مشابه زیر را در نظر بگیرید:

<div class="mx-3">
    <h1 style="font-size: 2rem">Comments</h1>
    <div class="my-4 d-flex">
        <input type="text" class="w-100 rounded border shadow py-2 px-3
mr-2 my-2" placeholder="Write your comment here...">
        <div class="py-2">
            <button type="submit" class="p-2 btn btn-success w-20 rounded shadow text-white">Add</button>
        </div>
    </div>
        <div class="rounded border shadow p-3 my-2">
            <div class="d-flex justify-content-between my-2">
                <div class="d-flex">
                    <p></p>
                </div>
            </div>
        </div>

</div>

که خروجی آن در آدرس http://localhost:8000 به شکل زیر است:

Livewire چیست

کار با Livewire

اکنون نوبت آن رسیده که نحوه‌ی کارکرد کامپوننتی که ایجاد کرده‌اید را مشاهده کنید تا بهتر درک کنید که livewire چیست و نحوه کارکرد آن چگونه است.

تعریف property و method

برای این منظور در کامپوننت Comments، خصوصیت comments را به شکل آرایه برای ذخیره‌ی موقت نظرات و خصوصیت newComment را برای نظر جدید ایجاد کنید. متد addCommnet را هم برای افزودن نظر به آرایه‌ی فوق تعریف ‌کنید. برای راحتی کار فعلا از ذخیره‌ی نظر در دیتابیس صرف‌نظر ‌کنید.

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Comments extends Component
{
    public $comments = [];
    public $newComment;

    public function addComment()
    {
        array_unshift($this->comments, [
            'body' => $this->newComment,
        ]);

        $this->newComment = '';
    }

    public function render()
    {
        return view('livewire.comments');
    }
}

نکته‌ی مهمی که وجود دارد این است که خصوصیاتی که در کامپوننت به صورت public تعریف می‌کنیم، در view قابل دسترسی‌اند بدون این‌که نیاز باشد آن‌ها را به متد view() در تابع render() پاس دهیم. پس در فایل comments.blade.php برای نمایش نظرها یک حلقه‌ی foreach تعریف کنید:

<div class="mx-3">
    <h1 style="font-size: 2rem">Comments</h1>


    <div class="my-4 d-flex">
        <input type="text" class="w-100 rounded border shadow py-2 px-3 mr-2 my-2" placeholder="Write your comment here...">
        <div class="py-2">
            <button type="submit" class="p-2 btn btn-success w-20 rounded shadow text-white">Add</button>
        </div>
    </div>
        @foreach($comments as $comment)
    <div class="rounded border shadow p-3 my-2">
        <div class="d-flex justify-content-between my-2">
            <div class="d-flex">
                <p>{{ $comment['body'] }}</p>
            </div>
        </div>
    </div>
        @endforeach

</div>

Bind کردن داده‌ها

اگر تجربه‌ی استفاده از فریم ورک‌های فرانت‌اند مانند Vue یا Angular را داشته باشید، با این مفهوم آشنا هستید. Livewire می‌تواند مقدار یک تگ HTML را با یک خصوصیت خاص در کامپوننت، Bind کند یا به عبارتی پیوند دهد:

<div class="mx-3">
    <h1 style="font-size: 2rem">Comments</h1>

    <div class="my-4 d-flex">
        <input type="text" class="w-100 rounded border shadow py-2 px-3 mr-2 my-2" placeholder="Write your comment here..." wire:model="newComment">
        <div class="py-2">
            <button type="submit" class="p-2 btn btn-success w-20 rounded shadow text-white">Add</button>
        </div>
    </div>
        @foreach($comments as $comment)
    <div class="rounded border shadow p-3 my-2">
        <div class="d-flex justify-content-between my-2">
            <div class="d-flex">
                <p>{{ $comment['body'] }}</p>
            </div>
        </div>
    </div>
        @endforeach

</div>

به تگ input در کد فوق نگاه کنید. زمانی که کاربر عبارتی را در تگ input فوق تایپ می‌کند، با تایپ هر کاراکتر توسط کاربر، بسته به سرعت تایپ، درخواستی به صورت Ajax به سمت سرور ارسال شده و پاسخ مربوط بر‌گردانده می‌شود. معمولا wire:model در تگ‌های HTML زیر مورد استفاده قرار می‌گیرد:

<input type="text">
<input type="radio">
<input type="checkbox">
<select>
<textarea>

اکشن‌ها

هدف از تعریف اکشن، ایجاد ارتباطی پویا بین View و کامپوننت و صدا زدن متدها در View، هنگام یک رویداد خاص است. فرمت کلی کار به صورت زیر است:

wire:[dispatched browser event]="[action]"

پس به تگ button در فایل comments، اکشن addComment را اضافه کنید:

<div class="mx-3">
    <h1 style="font-size: 2rem">Comments</h1>

    <div class="my-4 d-flex">
        <input type="text" class="w-100 rounded border shadow py-2 px-3 mr-2 my-2" placeholder="Write your comment here..." wire:model="newComment">
        <div class="py-2">
            <button type="submit" class="p-2 btn btn-success w-20 rounded shadow text-white" wire:click="addComment">Add</button>
        </div>
    </div>
        @foreach($comments as $comment)
    <div class="rounded border shadow p-3 my-2">
        <div class="d-flex justify-content-between my-2">
            <div class="d-flex">
                <p>{{ $comment['body'] }}</p>
            </div>
        </div>
    </div>
        @endforeach

</div>

اگر به تگ button در کد فوق دقت کنید، متوجه خواهید شد که در این تگ رویداد کلیک را به اکشن موردنظرمان bind کرده‌ایم. اکشن باید هم‌نام متدی باشد که در کامپوننت تعریف کرده‌ایم. بنابراین با کلیک بر روی دکمه‌ی button، یک درخواست Ajax به سمت سرور ارسال می‌شود، متد addComment که در کامپوننت تعریف کرده‌ایم اجرا شده و نتیجه به سمت سرور برمی‌گردد.

برخی از رویدادهایی که در اکشن‌ها فراخوانده می‌شوند، شامل click، keydown و submit هستند.

اکنون در صفحه‌ای که ایجاد کرده‌اید، با افزودن نظر می‌بینید که به صورت پویا و بدون نیاز به Refresh صفحه، نظر جدید به لیست نظرات افزوده می‌شود.

استفاده از Modifireها

اگر تگ div که تگ‌های button و input را در برگرفته را به تگ form تغییر دهید و در واقع یک فرم ایجاد کنید، می‌توانید از رویداد submit استفاده کنید:

<div class="mx-3">
    <h1 style="font-size: 2rem">Comments</h1>

    <form class="my-4 d-flex" wire:submit.prevent="addComment">
        <input type="text" class="w-100 rounded border shadow py-2 px-3 mr-2 my-2" placeholder="Write your comment here..." wire:model="newComment">
        <div class="py-2">
            <button type="submit" class="p-2 btn btn-success w-20 rounded shadow text-white">Add</button>
        </div>
    </form>
        @foreach($comments as $comment)
    <div class="rounded border shadow p-3 my-2">
        <div class="d-flex justify-content-between my-2">
            <div class="d-flex">
                <p>{{ $comment['body'] }}</p>
            </div>
        </div>
    </div>
        @endforeach

</div>

می‌بینید که دیگر نیازی به استفاده از رویداد click در تگ button نیست. اما در این حالت اگر از submit به تنهایی استفاده کنیم، صفحه Refresh می‌شود. چاره‌ی کار، استفاده از یک modifier است که با dot یا نقطه به رویداد اصلی متصل می‌شود. modifire‌ها می‌توانند قابلیت‌هایی را به یک رویداد اضافه کنند. برخی از modifier‌ها عبارتند از: self، stop، prevent و ... .

modifier ما در اینجا prevent است که با استفاده از آن، صفحه دیگر Refresh نخواهد شد. این modifier معادل ()event.preventDefault در جاوا اسکریپت است.

برای جلوگیری از ارسال درخواست‌های متعدد در wire:model نیز می‌توانید به صورت زیر از یک modifier استفاده کنید:

<div class="mx-3">
    <h1 style="font-size: 2rem">Comments</h1>

    <form class="my-4 d-flex" wire:submit.prevent="addComment">
        <input type="text" class="w-100 rounded border shadow py-2 px-3 mr-2 my-2" placeholder="Write your comment here..." wire:model.debounce.500ms="newComment">
        <div class="py-2">
            <button type="submit" class="p-2 btn btn-success w-20 rounded shadow text-white">Add</button>
        </div>
    </form>
        @foreach($comments as $comment)
    <div class="rounded border shadow p-3 my-2">
        <div class="d-flex justify-content-between my-2">
            <div class="d-flex">
                <p>{{ $comment['body'] }}</p>
            </div>
        </div>
    </div>
        @endforeach

</div>

در این حالت، 500 میلی‌ثانیه پس از آپدیت شدن input، در این‌جا یعنی 500 میلی‌ثانیه پس از توقف تایپ، یک درخواست به سمت سرور ارسال می‌شود. این مقدار را می‌توانید به مقادیر دلخواه بر حسب میلی‌ثانیه تغییر دهید.

بررسی درخواست Ajax

اکنون برای آن که بهتر درک کنیم Livewire چیست و چگونه کار می‌کند، درخواست ارسالی در رویداد submit را با هم بررسی می‌کنیم. ساختار تمام درخواست‌های ارسالی دیگر نیز، با اندکی تفاوت در جزئیات و مقادیر، مشابه است:

Livewire چیست

آدرسی که درخواست‌های Ajax به آن فرستاده می‌شوند، http://localhost:8000/livewire/message/comments است که تعریف و ایجاد آن بر عهده‌ی Livewire است و وظیفه‌ی ارتباط با کامپوننت comments را بر عهده دارد. بسته به کامپوننتی که می‌خواهیم با آن ارتباط برقرار کنیم، این آدرس تغییر می‌کند.

در اطلاعات درخواستی که ارسال می‌شود، سه آرایه‌ی json وجود دارد:

آرایه‌ی fingerprints، شامل این موارد است: id که خاص تگ موردنظر است، locale که در پروژه‌ی موردنظر ما en یا انگلیسی می‌باشد و name که نام کامپوننت را در برمی‌گیرد.

در آرایه‌ی serverMemo، مقادیر مختلفی وجود دارد که مهم‌ترین آن آرایه‌ی data است. در این آرایه، مقدار خصوصیات تعریف شده برای کامپوننت، قرار می‌گیرند.

در آرایه‌ی updates نیز تغییرات ایجاد شده به سمت سرور ارسال می‌شوند. در ایندکس‌های مختلف این آرایه، نام و مقدار جدید خصوصیت در آرایه‌ی payload و نوع رویدادی که فراخوانی شده، قرار دارند.

در اطلاعات برگشتی نیز، دو آرایه با نام‌های effects و serverMemo وجود دارد.

آرایه‌ی effects شامل آرایه‌ی dirty و رشته‌ی html است. آرایه‌ی dirty کلیدهای مقادیر خصوصیات را در خود نگه می‌دارد و رشته‌ی html، کدهای html کل کامپوننت را در صورت وجود مقدار برگشتی جدید، به کلاینت ارسال می‌کند.

آرایه‌ی serverMemo نیز مانند همان آرایه‌ی موجود در اطلاعات ارسالی (با کلیدهای کمتر) است و مقادیر جدید خصوصیات را به سمت کلاینت ارسال می‌کند.

قسمت‌های دیگر این آموزش:

جمع‌بندی:

در این مقاله از سری مقالات آموزش لاراول، توانستیم یاد بگیریم که Livewire چیست و چه کاربردی دارد، نحوه‌ی کارکرد آن را درک کنیم و با عناصر اصلی آن و نحوه‌ی کار با آن‌ عناصر آشنا شویم. هم‌چنین ساختار درخواست‌های Ajax ارسالی به سمت سرور را نیز به طور جزیی مورد بررسی قرار دادیم تا هرچه بهتر بتوانید نحوه‌ی کارکرد فریم‌ورک Livewire در لاراول را درک کنید.

در مقاله‌ی بعد به معرفی بخش‌های دیگری از این فریم ورک می‌پردازیم و نحوه‌ی استفاده از آن‌ها را فرا می‌گیریم. پروژه‌ای که شروع کرده‌ایم را توسعه داده و ویژگی‌های جدیدی به آن می‌افزاییم و ارتباط با دیتابیس را نیز برقرار خواهیم کرد.

خوشحال می‌شویم نظرات، تجربیات و سوالات خود را با ما و سایر کاربران سون لرن به اشتراک بگذارید.

اگر به یادگیری بیشتر لاراول علاقه دارید می‌توانید در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه‌ها به صورت کامل برنامه‌ نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.

چه امتیازی به این مقاله می دید؟
نویسنده رضا زیدی
از یادگیری ، عمل‌گرایی و چالش‌های مربوطه ، لذت می‌برم ...

نظرات کاربران

حسین

عالی

رضا زیدی

خوشحالم که این مقاله برات مفید بوده حسین جان
مرسی از حسن توجهت

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :