Skip to content

Instantly share code, notes, and snippets.

@eimg
Last active January 30, 2024 06:53
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eimg/a29bbd6d612439d2f3f03c2986daf5f2 to your computer and use it in GitHub Desktop.
Save eimg/a29bbd6d612439d2f3f03c2986daf5f2 to your computer and use it in GitHub Desktop.
Livewire Tutorial

Laravel Livewire Tutorial

Laravel ကို ဘယ် Front-end နည်းပညာနဲ့မဆို တွဲဖက်အသုံးပြုလို့ရပါတယ်။ အဲ့ဒီလို တွဲဖက်အသုံးပြုလို့ရတဲ့ နည်းပညာတွေထဲက Livewire အကြောင်းကို တစ်ခါထဲ လက်တွေ့လိုက်လုပ်ကြည့်လို့ရမယ့် Tutorial ပုံစံနဲ့ ဖော်ပြသွားမှာပါ။ Livewire ကို အကျဉ်းချုပ်အားဖြင့် JavaScript တွေရေးစရာမလိုတော့ဘဲ PHP နဲ့ပဲ Sing-Page Application (SPA) တွေ ဖန်တီးလို့ရတဲ့ နည်းပညာလို့ ဆိုနိုင်ပါတယ်။

Project Setup

စမ်းသပ်ကြည့်နိုင်ဖို့အတွက် ပထမဆုံး Laravel ပရောဂျက် အသစ်တစ်ခုကို အခုလို တည်ဆောက်ယူလိုက်ပါ။

composer create-project laravel/laravel tall

နမူနာအရ tall ဆိုတဲ့ ဖိုဒါအမည်နဲ့ Laravel ပရောဂျက်သစ်တစ်ခု ရရှိသွားပါလိမ့်မယ်။ ပရောဂျက်ဖိုဒါထဲကို cd tall နဲ့ဝင်ပြီး Laravel Breeze ကို အခုလို Install လုပ်လိုက်ပါ။

composer require laravel/breeze --dev

Laravel Breeze ဟာ အသင့်သုံး User Authentication System ကို Tailwind တို့ Livewire တို့နဲ့ ရေးပေးထားတဲ့ Official Package တစ်ခုဖြစ်ပါတယ်။ ဒီ Package ကို Install လုပ်လိုက်ခြင်းအားဖြင့် User Authentication အပြင် Tailwind တို့ Livewire တို့လည်း တစ်ခါထဲ ထည့်သွင်းပါဝင်သွားပြီး ဖြစ်စေပါတယ်။ ကိုယ့်ဘာသာ တစ်ခုချင်း ထပ်ထည့်စရာ မလိုတော့ပါဘူး။

ပြီးတဲ့အခါ လိုအပ်တဲ့ Setup တွေ ပြုလုပ်စေဖို့အတွက် ဒီ Command ကို Run ပေးပါ။

php artisan breeze:install

လာမေးတဲ့ မေးခွန်းတွေထဲက Livewire with Alpine ကို ရွေးပေးပါ။ ဒါဆိုရင် Livewire ကို အသုံးပြုပြီး လိုအပ်တဲ့ Setup တွေကို သူက လုပ်ပေးသွားမှာပါ။ ကျန်မေးခွန်းတွေကိုတော့ အခုထည့်ကြည့်မယ့်ထဲမှာ မပါသေးလို့ နှစ်သက်ရာသာ ရွေးလိုက်ပါ၊ ရပါတယ်။

breeze:install

ဆက်လက်ပြီး စမ်းကြည့်စရာ Data ရအောင် Migrate တွေ Seed တွေ လုပ်ကြပါမယ်။ အရင်ဆုံး .env ဖိုင်မှာ DB_DATABASE=laravel ကို DB_DATABASE=tall လို့ ပြင်ပေးပြီး migrate Run ပေးလိုက်ပါ။

php artisan migrate

Migration Run စဉ်မှာ Database မရှိသေးလို့ ဆောက်မှာလားမေးရင် Yes လို့ ရွေးပေးပါ။ ပြီးတဲ့အခါ Sample Data လေးတစ်ချို့ ထည့်ဖို့အတွက် database/seeders/DatabaseSeeder.php မှာ Comment ပိတ်ထားတဲ့ ဒီလိုင်းလေးကို ဖွင့်ပေးလိုက်ပါ။

\App\Models\User::factory(10)->create();

Seed Run ပြီး Sample Data ထည့် လို့ရပါပြီ။

php artisan db:seed

Running Servers

Server တွေ Run ဖို့ရယ်၊ လိုအပ်တဲ့ Command Run ဖို့ရယ် Terminal (၃) ခုလိုပါမယ်။ Server တွေကို Background Service အနေနဲ့ Run ပြီး Manage လုပ်တတ်ရင်တော့ တစ်ခုထဲလည်း ရပါတယ်။ ဒါပေမယ့် ဒီနေရာမှာတော့ ရှင်းသွားအောင် (၃) ခုခွဲသုံးတယ်လို့သာ သဘောထားပါ။ အရင်ဆုံး Terminal တစ်ခုမှာ Client-side Dev Server ကို အခုလို Run လိုက်ပါ။

npm run dev

Run လက်စကို ပိတ်လိုက်လို့ မရပါဘူး။ ဒီအတိုင်း Run ထားရမှာပါ။ Terminal နောက်တစ်ခုနဲ့ PHP Dev Server ကို အခုလို Run လိုက်ပါ။

php artisan serve

သူလည်း Run လက်စကို ပိတ်လိုက်လို့ မရပါဘူး။ ဒီအတိုင်း ဆက် Run ထားရမှာပါ။ Browser မှာ localhost:8000 နဲ့ စမ်းကြည့်လို့ရပါပြီ။

Creating Livewire Components

ဆက်လက်ပြီး နောက် Terminal တစ်ခုမှာ အခုလို Run ပြီး လိုအပ်တဲ့ Livewire Component တွေ View တွေဖန်တီးလိုက်ပါ။

php artisan livewire:layout
php artisan make:livewire users.user-list
php artisan make:livewire users.user-detail
php artisan make:livewire users.user-add

ပထမ Command က resources/views/components/layouts/app.blade.php အမည်နဲ့ Main Layout View ဖိုင်တစ်ခုကို တည်ဆောက်ပေးသွားမှာဖြစ်ပါတယ်။ Livewire Component တွေအတွက် Component Class ဖိုင်တွေကို app/Livewire ထဲမှာ တည်ဆောက်ပေးသွားမှာ ဖြစ်ပြီး သူနဲ့တွဲဖက်သုံးဖို့အတွက် View ဖိုင်တွေကို resources/views/livewire ထဲမှာ တည်ဆောက်ပေးသွားမှာ ဖြစ်ပါတယ်။ ဒါကြောင့် make:livewire Command (၃) ခုကနေ ရရှိလာမယ့် ဖိုင်တွေက ဒီလိုပါ

  • app/Livewire/Users/UserList.php
  • resources/views/livewire/users/user-list.blade.php
  • app/Livewire/Users/UserDetail.php
  • resources/views/livewire/users/user-detail.blade.php
  • app/Livewire/Users/UserAdd.php
  • resources/views/livewire/users/user-add.blade.php

Creating Layout View

resources/views/components/layouts/app.blade.php ထဲက ကုဒ်ကို အခုလိုပြင်ပေးလိုက်ပါ။

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport"
        content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>Livewire</title>

    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    <div class="min-h-screen bg-gray-100">
        <header class="bg-white shadow">
            <div class="flex max-w-5xl mx-auto py-6 px-4">
                <h2 class="font-semibold text-xl
                    text-gray-800 leading-tight">
                    Livewire
                </h2>

                <a class="text-green-600 ms-6"
                    href="/users/add" wire:navigate>+ Add User</a>
            </div>
        </header>
        <main class="max-w-3xl mx-auto py-6 px-4">
            {{ $slot }}
        </main>
    </div>
</body>
</html>

ဒီဖိုင်က Livewire Component တွေကို Full Page Component အနေနဲ့ ပြတဲ့အခါ Main Template အဖြစ် အသုံးပြုပေးမယ့်ဖိုင် ဖြစ်ပါတယ်။ အဓိကထူးခြားချက် နှစ်ချက်ပဲပါပါတယ်။ $slot နေရာမှာ Component ကို လာပြမှာဖြစ်ပြီး၊ <a> Element မှာ wire:navigate Attribute ပါသွားပါတယ်။ ဒါကြောင့် ဒီ <a> Element ကို နှိပ်တဲ့အခါ နောက်တစ်မျက်နှာအနေနဲ့ Page Reload နဲ့ မသွားတော့ဘဲ သက်ဆိုင်ရာ Component ကို နေရာမှာတင် Single-page အနေနဲ့ ပြောင်းပြီး ပြပေးသွားမှာပါ။ JavaScript တွေမလိုဘဲ PHP နဲ့ပဲ Single-page အလုပ်လုပ်အောင် ရေးလို့ရတယ်ဆိုတာ ဒီသဘောကို ပြောတာပါ။

Writing List Component

ပြီးတဲ့အခါ app/Livewire/User/UserList.php မှာ အခုလို ရေးပေးပါ။

<?php

namespace App\Livewire\Users;

use App\Models\User;
use Livewire\Component;

class UserList extends Component
{
    public function render()
    {
        return view('livewire.users.user-list', [
            "users" => User::all()
        ]);
    }
}

နဂို Auto-generated Code ကို နည်းနည်းပဲ ပြင်ထားပါတယ်။ render() Method မှာ View ကို ပြန်ပေးတဲ့အခါ User Model ကိုသုံးပြီး Seed လုပ်ထားတဲ့ Sample User တွေကိုပါ ထည့်ပေးလိုက်တာပါ။ ဒါက Component Class ပဲ ရှိပါသေးတယ်။ Component View ကို resources/views/livewire/users/user-list.blade.php မှာ အခုလို ရေးပေးလိုက်ပါ။

<ul class="mt-4">
    @foreach ($users as $user)
        <li class="border-b py-2 mb-2 flex justify-between"
            wire:key="{{ $user->id }}">

            <a href="/users/view/{{ $user->id }}"
                 class="text-blue-700" wire:navigate>
                {{ $user->name }}
            </a>

            <button wire:click="delete({{ $user->id }})"
                class="text-red-500 text-xl font-bold">
                &times;
            </button>
        </li>
    @endforeach
</ul>

သိပ်ရှုပ်ရှုပ်ယှက်ယှက် မဟုတ်ပါဘူး။ $users တွေကို Loop လုပ်ပြီး ပြထားလိုက်တာပါပဲ။ ကြည့်ကောင်းအောင် Tailwind Class တွေသုံးထားပေမယ့် အဓိကပိုကျတာက wire:key wire:navigate wire:click ဆိုတဲ့ Attribute တွေပါ။

wire:key ရဲ့ သဘောကိုတော့ React တို့ Vue တို့ လေ့လာဖူးသူတွေ သိကြပါလိမ့်မယ်။ Loop လုပ်ထားတဲ့ Item တွေမှာ Unique ဖြစ်တဲ့ Key Attribute ရှိမှသာ နောက်ပိုင်း အပြောင်းအလဲ ရှိတဲ့အခါ List တစ်ခုလုံးကို အစအဆုံး ပြန်ပြီး Render လုပ်စရာမလိုဘဲ လိုတဲ့အပိုင်းလေးပဲ ရွေးပြီး လုပ်လို့ရစေဖို့ ဖြစ်ပါတယ်။

wire:navigate ရဲ့သဘော အကျဉ်းချုပ်ကို အပေါ်မှာ ပြောခဲ့ပြီးပါပြီ။ wire:click ကတော့ Button ကို နှိပ်တဲ့အချိန်မှာ Run စေချင်တဲ့ Function (Component Method) ကို ပေးရတာပါ။ ပုံမှန်အားဖြင့် Button Click မှာ PHP ကုဒ်တွေ Run လို့မရပါဘူး။ Client-side, Server-side တူမှ မတူတာကိုး။ Run ချင်ရင် JavaScript ကုဒ်တွေဘဲ Run လို့ရမှာပါ။ Livewire က wire:click နဲ့ Button Click မှာ PHP ကုဒ်တွေ Run လို့ရအောင် လုပ်ပေးလိုက်တာပါ။ လောလောဆယ် ခေါ်ထားတဲ့ delete() Method က မရှိသေးပါဘူး။ နောက်မှရေးမှာပါ။ ကြိုခေါ်ထားလိုက်တာပါ။

ဆက်လက်ပြီး စတင်စမ်းသပ်နိုင်ဖို့အတွက် routes/web.php မှာ အခုလို Component တွေကို Import လုပ်ပြီး Route တစ်ချို့ ရေးထည့်ပေးလိုက်ပါ။

use App\Livewire\Users\UserAdd;
use App\Livewire\Users\UserDetail;
use App\Livewire\Users\UserList;

Route::get('/users', UserList::class);
Route::get('/users/view/{id}', UserDetail::class);
Route::get('/users/add', UserAdd::class);

ပုံမှန်အားဖြင့် Route ကနေ Controller တွေ View တွေကို လှမ်းချိတ်မှာပါ။ အခုတော့ Controller တွေ View တွေကို မချိတ်တော့ဘဲ စောစောက ရေးထားတဲ့ UserList Component ကို တိုက်ရိုက် လှမ်းချိတ်လိုက်တာပါ။ ဒါကြောင့် /users Route ကို သွားလိုက်ရင် UserList Component ကို Layout ထဲမှာ ထည့်ပြီး Full-page Component အနေနဲ့ ပြပေးလာမှာ ဖြစ်ပါတယ်။

ကျန်တဲ့ UserDetail တွေ UserAdd တွေ ထပ်မရေးခင် ဒီအဆင့်မှာတင် စတင်စမ်းသပ်ကြည့်လို့ရပါပြီ။

localhost:8000/users ကိုသွားကြည့်လိုက်ရင် အခုလိုရလဒ်ကို ရရှိမှာဖြစ်ပါတယ်။ Database Table ထဲက Users တွေကို UserList Livewire Component နဲ့ လာပြပေးနေခြင်းပဲ ဖြစ်ပါတယ်။

User List

Delete User Feature

User Delete လုပ်တာကတော့ လွယ်လွယ်လေးပါ။ wire:click နဲ့ Function ခေါ်ထားပြီးသားမို့လို့ UserList Class မှာ အခုလို Method တစ်ခု ထပ်တိုးပေးလိုက်ယုံပါပဲ။

public function delete($id)
{
    $user = User::find($id);
    $user->delete();
}

ရေးရိုးရေးစဉ်အတိုင်း User Model ကိုသုံးပြီး ဖျက်လိုက်တာပါ။ Livewire က delete() ကို ခေါ်ပေးတဲ့အပြင် React တို့ဘာတို့မှာ State ပြောင်းရင် Component လိုက်ပြောင်းပေးနိုင်သလိုပဲ Server-side ဘက်မှာ Data ပျက်သွားယုံသာမက Client-side List ကလည်း Page Refresh တွေဘာတွေ မလိုဘဲ အလိုအလျှောက် Update ဖြစ်သွားမှာ ဖြစ်ပါတယ်။

User View Feature

ဆက်လက်ပြီး resources/views/livewire/users/user-detail.blade.php မှာ အခုလိုရေးပေးပါ။

<div class="border rounded p-4">
    <h3 class="text-2xl mb-2">{{ $user->name }}</h3>
    <p class="text-gray-600 mb-2">{{ $user->email }}</p>
    <div class="mb-4">
        <small class="text-gray-400">
            {{ $user->created_at->diffForHumans() }}
        </small>
    </div>

    <a href="/users" class="text-blue-500" 
        wire:navigate>&laquo; Go back</a>
</div>

ဒီကုဒ်က သိပ်စိတ်ဝင်စားစရာ မကောင်းလှပါဘူး။ wire:navigate နဲ့ Link တစ်ခုပါပေမယ့် အခြေခံအားဖြင့် $user Data တွေကို Box လေးတစ်ခုနဲ့ ပြလိုက်တာပါပဲ။ ဒါပေမယ့် ဒီလိုပြနိုင်ဖို့အတွက် UserDetail Class မှာ အခုလိုရေးပေးဖို့ လိုပါတယ်။

<?php

namespace App\Livewire\Users;

use App\Models\User;
use Livewire\Component;

class UserDetail extends Component
{
    public $user;

    public function mount($id)
    {
        $this->user = User::find($id);
    }

    public function render()
    {
        return view('livewire.users.user-detail');
    }
}

ဒီမှာတော့ သတိပြုရမှာတွေပါလာပါပြီ။ ပထမဆုံး $user Property ကို ကြေညာထားပါတယ်။ ဒါကြောင့် View မှာ $user ကို အသုံးပြုလို့ရသွားပါပြီ။ ပြီးတဲ့အခါ mount() Method ကို သုံးပြီး User Model ရဲ့ အကူအညီနဲ့ User Data တွေထုတ်ယူထားပါတယ်။ ရလာတဲ့ Data တွေကို $user Property ထဲမှာ ထည့်ပေးလိုက်တာပါ။

ဒီနေရာမှာ Data ထုတ်ယူတဲ့ကုဒ်ကို render() မှာ မရေးဘဲ mount() မှာရေးတာက $id URL Parameter ကို လိုချင်လို့ပါ။ Route မှာ /users/view/{id} လို့ သတ်မှတ်ထားတဲ့အတွက် Controller Method တွေမှာ $id ကို ယူသုံးလို့ရသလိုပဲ mount() မှာလည်း ယူသုံးလို့ရပါတယ်။ mount() Method ဟာ Livewire ရဲ့ Lifecycle Method တွေထဲကတစ်ခုဖြစ်ပြီး Component ကို Render လုပ်တဲ့အချိန်တိုင်းမှာ အလိုအလျှောက် အလုပ်လုပ်တဲ့ Method တစ်ခုပါ။

ဒီလောက်ဆိုရင် User View လည်းရသွားပါပြီ။ List ထဲက User တစ်ယောက်ကို နှိပ်လိုက်ရင် Page Reload မလိုအပ်ဘဲ UserDetail Component ကို ပြပေးသွားမှာဖြစ်သလို၊ UserDetail က Go Back Link ကို နှိပ်လိုက်ရင်လည်း Page Reload မလိုဘဲ UserList ကို ပြန်ပြပေးသွားပါလိမ့်မယ်။

User Add Feature

User တွေအသစ်ထပ်ထည့်ဖို့အတွက် Form Template တစ်ခုလိုပါမယ်။ resources/views/livewire/users/user-add.blade.php မှာ အခုလိုရေးပေးပါ။

<form wire:submit="save">
    <input type="text" wire:model="name"
        class="w-full border rounded p-3"
        placeholder="Name">
    <div class="text-red-600 text-sm mb-3">
        @error('name') {{ $message }} @enderror
    </div>

    <input type="text" wire:model="email"
        class="w-full border rounded p-3"
        placeholder="Email">
    <div class="text-red-600 text-sm mb-3">
        @error('email') {{ $message }} @enderror
    </div>

    <button type="submit"
        class="rounded bg-blue-700 text-white py-2 px-6">
            Add User
    </button>
</form>

Validation Message တွေပါ ထည့်ပြထားလို့ နည်းနည်းရှုပ်သွားတယ်ထင်ရပေမယ့်၊ သေချာကြည့်ရင် သိပ်မရှုပ်ပါဘူး။ Name နဲ့ Email ကို Input နှစ်ခုနဲ့ တောင်းထားတဲ့ HTML Form တစ်ခုသာဖြစ်ပါတယ်။ အရေးအကြီးဆုံး ထူးခြားချက်ကတော့ <form> မှာ wire:submit နဲ့ save() ကို ခေါ်ထားခြင်းဖြစ်ပါတယ်။ ဒါကြောင့် ဒီ Form မှာ Submit နှိပ်လိုက်ရင် Page Reload နဲ့ Server Submit မလုပ်တော့ဘဲ UserAdd Class ရဲ့ save() Method ကို ခေါ်ပေးသွားမှာဖြစ်ပါတယ်။

နောက်ထပ်အရေးကြီးတာကတော့ Input တွေမှာပါတဲ့ wire:model ဖြစ်ပါတယ်။ လိုရင်းကတော့ Input ကို Class Property နဲ့ ချိတ်ပေးလိုက်တာပါ။ ဒါကြောင့် ဒီ Input တွေမှာ ရေးဖြည့်လိုက်သမျှ သက်ဆိုင်ရာ $name နဲ့ $email Property တွေထဲကို အလိုအလျှောက် ရောက်သွားမှာပါ။

Add Form

Blade @error Directive နဲ့ Validation Error ရှိမရှိစစ်ပြီး ရှိရင် တစ်ခါထဲ ပြခိုင်းထားပါတယ်။ ဒီ Form အလုပ်လုပ်ဖို့အတွက် လိုအပ်တဲ့ ကုဒ်တွေကို UserAdd Class မှာ အခုလို ရေးပေးပါ။

<?php

namespace App\Livewire\Users;

use App\Models\User;
use Livewire\Attributes\Rule;
use Livewire\Component;

class UserAdd extends Component
{
    #[Rule('required')]
    public $name = '';

    #[Rule('required|email')]
    public $email = '';

    public function save()
    {
        $this->validate();

        User::factory()->create([
            "name" => $this->name,
            "email" => $this->email,
        ]);

        $this->reset();

        return redirect("/users");
    }

    public function render()
    {
        return view('livewire.users.user-add');
    }
}

$name နဲ့ $email Property နှစ်ခုရှိတာကို သတိပြုကြည့်ပါ။ Property တွေကြေညာတဲ့အခါ Validation Attribute တွေနဲ့ Validation Rules တွေကို တစ်ခါထဲ ထည့်ရေးပြီး ကြေညာထားပါတယ်။ ဒါကြောင့် save() Method မှာ $this->validate() ကိုခေါ်လိုက်တဲ့အခါ သက်မှတ်ထားတဲ့ Rule များအတိုင်း Validation စစ်ပြီး Fails ဖြစ်ခဲ့ရင် ဆက်မလုပ်ဘဲ Validation Error တွေနဲ့ Component ကို ပြန်ပြပေးမှာ ဖြစ်ပါတယ်။

Validation Pass ဖြစ်ခဲ့ရင်တော့ User Model ရဲ့ Factory အကူအညီနဲ့ User အသစ် Create လုပ်လိုက်ပါတယ်။ Factory ကိုသုံးရတာက User အတွက် Password အပါအဝင် တစ်ခြားလိုအပ်တာတွေ ထည့်မပေးလိုတဲ့အတွက် ပေးချင်တဲ့ Name နဲ့ Email ကိုပဲ ပေးပြီး ကျန် Value တွေကို Factory မှာ သတ်မှတ်ထားတဲ့အတိုင်း ထည့်ပေးလိုက်စေချင်လို့ပါ။ Name တို့ Email တို့ကို Property တွေကနေ ရပါတယ်။ Property တွေက Input Value တွေပါပဲ။ wire:model နဲ့ချိတ်ပေးထားလို့ပါ။

$this->reset() က Property Value တွေကို ပြန် Clear လုပ်လိုက်တာပါ။ နောက်ဆုံးမှာ redirect() နဲ့ /users Route ကို ပြန်သွားခိုင်းတဲ့အခါ ထုံးစံအတိုင်း Livewire က Page Reload ပြန်မလုပ်တော့ဘဲ /users Route နဲ့ ချိတ်ထားတဲ့ UserList Component ကို ပြန်ပြပေးသွားမှာပဲ ဖြစ်ပါတယ်။

Conclusion

ဒီလောက်ဆိုရင် Livewire ရဲ့ အလုပ်လုပ်ပုံကို တော်တော်လေး သဘောပေါက်သွားလောက်ပြီလို့ ယူဆပါတယ်။ အလားတူလုပ်ဆောင်ချက်မျိုးရဖို့အတွက် JavaScript Framework တစ်ခုခုကိုသုံးပြီး ရေးရင်လည်း ရနိုင်ပေမယ့်၊ Back-end သပ်သပ် Front-end သပ်သပ် ခွဲပြီး Maintain လုပ်စရာမလိုတော့သလို API Call တွေကိုလည်း Management လုပ်စရာမလိုတော့ပါဘူး။ တစ်ချို့က သပ်သပ်စီ ခွဲရေးရတာကို နှစ်သက်နိုင်ပေမယ့် အခုလို Language တစ်မျိုးထဲနဲ့ Laravel Framework ထဲကနေ ထွက်စရာမလိုဘဲ စီမံရေးသားနိုင်ခြင်းဟာလည်း အသုံးဝင်တဲ့ နည်းပညာတစ်ခုပဲ ဖြစ်ပါတယ်။

နိဂုံးချုပ်အနေနဲ့ သတိပြုစေချင်တဲ့ အချက်ကတော့ လက်ရှိနမူနာကုဒ်မှာ M-V-C ရဲ့ C (ခေါ်) Controller လုံးဝ ပြုတ်သွားခြင်းပါပဲ။ Controller ကုဒ်တွေ ရေးရိုးရေးစဉ်အတိုင်း ဆက်ရေးလို့လည်း ရပါတယ်။ API ကုဒ်တွေပါမယ်ဆို မဖြစ်မနေ ထည့်ရေးရမှာပါ။ ဒါပေမယ့် အခုလို UI ပိုင်းအတွက်တော့ Controller မလိုအပ်ရင် မသုံးတော့ဘဲ Component ချင်း ချိတ်ဆက်ရေးသားသွားတယ်ဆိုတာ သတိပြုရမှာပဲ ဖြစ်ပါတယ်။

@r1d3rzz
Copy link

r1d3rzz commented Oct 5, 2023

ဆရာအခုလို သေချာ ရှင်းပြထားပေးတာ ကျေးဇူးတင်ပါတယ်ဆရာ

@zawminhtutx
Copy link

Thank you so much

@zeyartun
Copy link

zeyartun commented Oct 5, 2023

Thanks

@Sitnyein
Copy link

Sitnyein commented Oct 5, 2023

ဆရာအခုလို သေချာ ရှင်းပြထားပေးတာ ကျေးဇူးတင်ပါတယ်ဆရာ

@inhibitor255
Copy link

အကယ်၍ laravel project မှာ Tailwind css က မရတချက် ရတချက်ဖြစ်နေမယ်ဆိုရင် resources/css/app.css မှာ အောက်တွင်ဖော်ပြထားသော ပထမတစ်ခုအစား ဒုတိယတစ်ခုအားထည့်လိုက်ခြင်းဖြင့် အဆင်ပြေသွားမည်ဖြစ်သည်။

@tailwind base;
@tailwind components;
@tailwind utilities;

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

@yelynnpaing
Copy link

thanks Sir

@NyiNyiAung16
Copy link

Thank you sir. It really helps me to improve. I'm waiting to post more tutorials.

@smeemarket
Copy link

Well, I am learned, and thanks, sir.

@pyaeOnenex
Copy link

Thank you for sharing Sir.

@PiSloth
Copy link

PiSloth commented Oct 19, 2023

Thanks a lot!

@Paige218
Copy link

thank you, Saya!!

@Khant-Nyi-Thway
Copy link

Thanks Sir!

@kowinhtike
Copy link

Thanks Sir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment