ToDo App lagi, Tapi dengan Livewire
Kembali dari lanjutan kenalan dengan laravel lagi, sebelum masuk ke laravelnya sebenarnya yang membuat saya tertarik banget untuk mencoba lagi laravel adalahh package bernama Livewire. Dari demo yang saya lihat saya langsung suka karena paket ini seperti memberi kemampuan interaktif setara saat menggunakan javascript, bedanya ini “pure” php+html (blade komponen tepatnya).
Agar tidak terlalu kemana-mana tulisan ini dibagi ke dalam dua bagian, pertama sekilas mencoba-coba fitur dasar, dan yang kedua mari buat simple todo app, yah saya gak tahu mau bikin apa dan yang paling gampang ya todo app, jadi tanpa fafifu lebih banyak langsung saja.
Install Livewire
Memasang livewire sama dengan memasang package php pada umumnya dengan composer
composer require livewire/livewire
Gak perlu dulu yang aneh-aneh saya siapkan dulu satu url untuk menjadi playground, buka routes/web.php dan buat seperti berikut
Route::get('demo', function () { return view('demo'); });
Lalu di views, buat berkas dengan nama demo.blade.php, isikan standar html template, saya sedikit menambahkan cdn bootstrap aja biar sedikit lebih rapi
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> <title>Document</title> @livewireStyles() </head> <body> <div class="container"> <div class="col-12 col-md-10 col-lg-8"> <div class="card-body row no-gutters align-items-center"> <h1>Demo Livewire</h1> </div> </div> </div> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script> @livewireScripts() </body> </html>
Jika diperhatikan di html ada bagian terkait livewire, itu helper untuk load asset yang dibutuhkan agar livewire bisa bekerja.
First Component
Untuk membuat komponen livewire gunakan cli artisan seperti berikut
php artisan make:livewire demo # demo di sini nama komponen yang saya buat, bisa diganti dengan nama yang dimau
Perintah ini akan membentuk 2 berkas, satu di app/Http/Livewire/Demo.php dan satu lagi di resources/views/livewire/demo.blade.php
Untuk berkas pertama isinya seperti berikut
<?php namespace App\Http\Livewire; use Livewire\Component; class Demo extends Component { public function render() { return view('livewire.demo'); } }
sedangkan berkas kedua murni html blade biasa
<div> // html komponen </div>
Berkas pertama, class Demo itu bisa dianggap sebagai controller, sehingga semua logic akan bermain di sini, dan yang kedua adalah berkas blade yang nantinya akan berkomunikasi secara langsung dengan class Demo ini.
Model Binding
Tambahkan public properti di berkas Livewire/Demo.php seperti berikut
class Demo extends Component { public $title = 'Demo Livewire'; public function render() { return view('livewire.demo'); } }
Lalu di komponen blade livewire panggil variable $title
<h1>{{ $title}}</h1>
Lalu yang paling menarik adalah ini, bindingnya. Mirip dengan v-model di Vue namun sekali lagi ini “pure” html php, tambahkan textbox di komponen blade tadi menjadi seperti berikut
<div> <input type="text" class="form-control form-control-lg form-control-borderless" wire:model="title"> <h1>{{ $title}}</h1> </div>
hasilnya?
Membuat Todo App
Segitu aja dulu, dari sedikit tentang model binding, sekaran mari iseng buat todo app yang menurut saya cukup lumayan dan interaktif walau saya tidak menulis satu baris javascript apapun.
Buat livewire todo dan task, todo sebagai parent dan task sebagai child
php artisan make:livewire todo php artisan make:livewire task
Seperti biasa, tambahkan saja langsung route baru untuk fokus terkait todo app ini.
Route::get('todo', function () { return view('todo'); });
jangan lupa berkas resources/views/todo.blade.php dan isikan seperti berikut
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> <title>Document</title> @livewireStyles() </head> <body> <div class="container"> <br/> <div class="row justify-content-center"> @livewire('todo') </div> </div> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script> @livewireScripts() </body> </html>
gak pake database-database cukup mainin array, buka berkas livewire/Todo.php buat seperti ini
<?php namespace App\Http\Livewire; use Livewire\Component; class Todo extends Component { public $task = ''; public $tasks = []; public function submit() { array_push($this->tasks, $this->task); $this->tasks = $this->tasks; $this->task = ''; } public function render() { return view('livewire.todo'); } }
Buka berkas livewire\todo.blade.php, ubah menjadi seperti ini
<div class="col-12 col-md-10 col-lg-8"> <form class="card card-sm" wire:submit.prevent="submit"> <div class="card-body row no-gutters align-items-center"> <div class="col-auto"> <i class="fas fa-search h4 text-body"></i> </div> <!--end of col--> <div class="col"> <input wire:model="task" class="form-control form-control-lg form-control-borderless" type="text" placeholder="Add task"> </div> <!--end of col--> <div class="col-auto"> <button class="btn btn-lg btn-success">Add</button> </div> <!--end of col--> </div> </form> <br> <div class="row justify-content-center"> <ul class="list-group"> @foreach ($tasks as $name) @livewire('task', ['task' => $name], key($name)) @endforeach </ul> </div> </div>
Sekarang childnya untuk menampung task, ubah livewire\task.blade.php buat seperti ini
@if ($done) <li class="list-group-item d-flex justify-content-between align-items-center"><s>{{ $task }}</s></li> @else <li class="list-group-item d-flex justify-content-between align-items-center">{{ $task }} <input type="checkbox" wire:model="done"></li> @endif
sedangkan pada berkas livewire\Task.php Buat sepert ini untuk menambahkan fungsi menyelesaikan tugas.
<?php namespace App\Http\Livewire; use Livewire\Component; class Task extends Component { public $task; public $done = false; public function render() { return view('livewire.task'); } }
Sehingga hasil akhir seperti berikut
Referensi
https://laravel-livewire.com/docs/2.x/quickstart