• Czas czytania ~12 min
  • 13.07.2022

Laravel Livewire to pełnowymiarowy framework Laravel do budowania dynamicznych interfejsów. W nie tak odległej przeszłości, aby zbudować aplikację za pomocą Laravel, musiałeś:

  1. Write Blade templates and render your app on the server side
  2. Write your backend as APIs that accept and respond with JSON, and then have a frontend framework like Vue, React, or Angular to consume the APIs and implement the UI

Ale teraz mamy trzecią opcję: Livewire. Chciałbym zagłębić się w zalety i wady opcji 1 i 2 powyżej, ale to już zostało zrobione sprawiedliwie w tym dobrze napisanym poście tutaj.

W tym artykule zagłębimy się w Livewire i zobaczymy, jak można go zastosować w rzeczywistych aplikacjach.

Co zbudujemy Zbudujemy

prostą aplikację blogową z następującymi funkcjami:

  1. Anyone can create an account and log in
  2. Logged-in users can create and update their own posts
  3. Anyone can read posts

Wymagania wstępne i konfiguracja

Ten samouczek zakłada, że masz dość duże doświadczenie z Laravel (zauważ, że ten samouczek używa Laravel 7.x). Nie jest wymagane żadne wcześniejsze doświadczenie z Livewire - myślę, że dlatego tu jesteśmy.

Oczywiście, aby rozpocząć, musimy mieć skonfigurowane nasze środowisko programistyczne. Najpierw utwórz nową aplikację Laravel:composer create-project --prefer-dist laravel/laravel:

^7.0 blog-wire

Następnie zainstaluj pakiet Livewire z composer:

composer require livewire/livewire

Utwórz nową bazę danych i dodaj poświadczenia bazy danych do .env pliku. I to wszystko, czego potrzebujemy, aby rozpocząć "Livewiring"!

Jak działa Livewire?

Zanim zaczniemy, dobrze jest mieć pojęcie, jak Livewire robi swoje. Krótko mówiąc:

  • Livewire renderuje początkowe dane wyjściowe komponentu na stronie — tak, jak typowy szablon Blade renderowany na serwerze
  • Gdy dochodzi do interakcji, Livewire wysyła żądanie AJAX do serwera ze zaktualizowanymi danymi
  • Serwer ponownie renderuje komponent i odpowiada zaktualizowanym kodem HTML
  • Livewire następnie inteligentnie mutuje DOM zgodnie ze zmianą

Jak widać, to tak, jakby mieć frontend i backend w jednym miejscu, bez potrzeby powtarzania logiki.

Kluczowe pojęcia w Livewire Aktywacja Livewire na stronie Aby Livewire działał na stronie, musisz dołączyć style i skrypty Livewire

na każdej stronie

, która ich potrzebuje. Zwykle trafiają one do szablonu podstawowego. Zrobisz to za pomocą @livewireStyles komponentów @livewireScripts

//app.blade.php
<!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">
    <title>@yield('title')</title>
    @livewireStyles
</head>
<body>
    @yield('content')
    @livewireScripts
</body>
</html>

Livewire does all of its goodness around its components. are quite similar to typical Laravel Blade class-based components. Let’s take a quick look at the two.

Tworzenie komponentu

Laravel Blade Komponent Laravel Blade można utworzyć, uruchamiając następujące polecenie:php artisan make:

component Alert

Spowoduje to utworzenie nowego Alert.php pliku klasy i umieszczenie go w folderzeApp\Views\Components. Następnie tworzony jest odpowiedni szablon widoku i umieszczany w resources/views/componentsprogramie . Aby wyświetlić składnik, można użyć następującej składni bloku: <x-alert/>.

Możesz dokładniej zbadać komponenty Laravel Blade w dokumentacji.

Tworzenie komponentu

Livewire Aby utworzyć komponent Livewire, uruchom następujące polecenie:php artisan make:

livewire Alert

Polecenie utworzy również dwa nowe pliki: app\Http\Livewire\Alert.php i szablon resources/views/livewire/alert.phpwidoku .

Komponent Livewire można renderować za pomocą lub <livewire:alert /> @livewire('alert').

As you can see, the commands look quite similar. The only major difference is that with , there’s a real-time sync (no page refresh required) between the component class and its view template. We will see how this works shortly.

Właściwości Livewire Właściwości

publiczne klas komponentów są udostępniane w widoku szablonu komponentu. Na tym się nie kończy — wartość właściwości jest synchronizowana w czasie rzeczywistym z widokiem, dzięki czemu po zaktualizowaniu wartości właściwości w widoku jest ona automatycznie aktualizowana w klasie komponentu.

//App\Http\Livewire\Alert.php
<?php
class Alert extends Component{
  public $message = "Our alert message";
}

// livewire/alert.blade.php
<div>
  <input wire:model="message">
  <br/>
  {{ $message }}
</div>

Aby powiązać właściwość komponentu z elementem wejściowym HTML, należy użyć następującego sytax:wire:

model="nazwa właściwości"

By typing into the input box, you will see the value of $message updating in real time. This is very similar to the concept of data binding in frameworks like Vue.js, React, and Angular. Learn more about Właściwości Livewire Właściwości here.

Akcje

Livewire Podobnie jak można powiązać dane w szablonie widoku z publicznymi właściwościami komponentów, można również mapować zdarzenia po stronie klienta na metody w komponentach. Na przykład, można reagować na zdarzenia kliknięcia, keyup i keydown, itp. za pomocą metod zdefiniowanych w klasie komponentu.

Spójrzmy na przykład:

<?php

use Livewire\Component;
class PostAlert extends Component{
  public $liked = true;
  public function render(){
    return view('livewire.post-alert');
  }

  public function toggleLike(){
    $this->liked = !$this->liked;
  }
}


// livewire/post-alert.blade.php
<div>
    <h4>Seeing livewire action in action 😜</h4>
    <button class="btn btn-primary" wire:click="toggleLike()">
        Like
    </button>
    @if ($liked)
        <i class="fa fa-heart text-danger h4"></i>
    @else
        <i class="fa fa-heart text-secondary h4"></i>
    @endif
</div>

W powyższej klasie komponentów utworzyliśmy metodętoggleLike(), która przełącza wartość właściwości na jej przeciwną wartość liked logiczną. W widoku szablonu mamy przycisk i ikonę serca, która jest w kolorze czerwonym lub szarym w zależności od wartości liked właściwości.

Użyliśmy składni wire:click=[action name] do powiązania metody toggleLike ze zdarzeniem click.

Livewire Action ToggleLike Event
Livewire action toggling a button.

A lot Livewire’s use cases revolve around properties and actions, and as such, they are very important to understand. These concepts can be applied to things like create form, edit form, delete form, etc. Read more about Akcje here.

Walidacja danych Livewire sprawia, że walidacja

danych jest bezproblemowa. Aby sprawdzić poprawność danych pochodzących z widoku szablonu formularza, należy napisać $rules właściwość zawierającą reguły sprawdzania poprawności, tak jak w przypadku Laravel. Następnie należy wywołać $this→validate() metodę w trakcie walidacji.

Spójrzmy na formularz do tworzenia wpisu na blogu:

 ...
class CreatePost extends Component
{
    public $title, $body;
    public $success;
    protected $rules = [
        'title' => 'required|string|max:220',
        'body' => 'required'
    ];

    public function render()
    {
        return view('livewire.create-post')
            ->extends('layouts.app')
            ->section('content');
    }
    public function create(){
        $this->validate();
        Post::create([
            'title' => $this->title,
            'slug' => Str::slug($this->title),
            'body' => $this->body,
            'author_id' => auth()->id()
        ]);

        $this->success = true;
    }
}


// livewire/create-post
<div class="container">
    @if ($success)
        <div class="alert alert-success">
            Post has been created successfully
        </div>
    @endif
    <form wire:submit.prevent="create">
        <div class="form-group">
            <label for="Post title">Post title</label>
            <input wire:model="title" type="text" name="title" id="title" class="form-control" placeholder="Title of the post">
            @error('title') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="form-group">
            <label for="Post body">Post Body</label>
            <textarea name="body" id="body" placeholder="Body of post here..." wire:model="body" class="form-control"></textarea>
            @error('body') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div>
            <button class="btn btn-primary" type="submit">Publish</button>
        </div>
    </form>
</div>
 
W powyższym kodzie formularza, gdy użytkownik przesyła wpis i nie przechodzi weryfikacji, wyświetlane są błędy sprawdzania poprawności, a wszystko to bez odświeżania strony.

Pierwsze kroki z Laravel Livewire

Dość powiedział - przejdźmy do działania. Możesz śledzić w repozytorium GitHub, gdy tworzymy naszą aplikację demonstracyjną.

Ponieważ chcemy, aby zalogowani użytkownicy mogli zarządzać własnymi postami, muszą najpierw utworzyć konto. Użyjemy do tego wbudowanego systemu uwierzytelniania Laravel.

Najpierw zainstaluj pakiet laravel/ui composer

:composer require laravel/ui

Następnie uruchom php artisan ui vue --auth rusztowanie całego systemu uwierzytelniania, a następnie php artisan migrate wykonaj migrację bazy danych.

N.B., most of the things we used to do with controllers will now be done using .

Przejdźmy do tworzenia modelu potrzebnego dla naszej aplikacji postów na blogu, :

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
    use SoftDeletes;

    protected $guarded = [];
    public function author(){
        return $this->belongsTo(User::class, 'author_id', 'id');
    }
}

Teraz utworzymy nasz plik migracji, App\Post
php artisan make:migration create_posts_table--table=posts:

Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug')->unique();
            $table->longText('body');
            $table->integer('author_id');
            $table->timestamps();
            $table->softDeletes();
});

Tworzenie komponentów

Będziemy tworzyć komponent dla każdej akcji bloga, którą chcemy, tj. Utwórz post, edytuj post, wyświetlaj listy postów i wyświetlaj post. Idźmy dalej i stwórzmy komponenty:

  • php artisan make:livewire CreatePost
  • php artisan make:livewire EditPost
  • php artisan make:livewire ListPost
  • php artisan make:livewire HomePost
  • php artisan make:livewire ReadPost

Możemy renderować komponent Livewire bezpośrednio z tras takich jak: Route::get('/posts/create', [\App\Http\Livewire\CreatePost::

class, '__invoke'])->middleware('auth');

Instead of calling controller actions, we will be routing to the , as shown above. Let’s now add all the routes we’ll need in web.php:

Route::get('/', function () {
    return view('index');
});
Auth::routes();
Route::get('/post/{slug}', [\App\Http\Livewire\ReadPost::class, '__invoke']);
Route::get('/home', '[email protected]')->name('home');
class, '__invoke'])->middleware('auth');
Route::get('/posts/{id}/edit', [\App\Http\Livewire\EditPost::class, '__invoke'])->middleware('auth');

//ListPost.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class ListPost extends Component
{
    public function render()
    {
        $posts = \App\Post::latest()->paginate(20);
        return view('livewire.list-post', ['posts' => $posts])
            ->extends('layouts.app')
            ->section('content');
    }
}



//livewire/list-post.blade.php
<div>
    <h4>My Posts <a href="{{ url('posts/create') }}" class="btn btn-primary"><i class="fa fa-plus"></i> Add new</a></h4>
    <ul class="list-group list-group-flush">
        @forelse ($posts as $post)
            <li class="list-group-item">

                <div class="float-right">
                    <a href='{{ url("posts/{$post->id}/edit") }}' class="btn btn-primary"><i class="fa fa-edit"></i> Edit</a>
                </div>
                <div>
                    <h5>{{ $post->title }}</h5>
                    <p>{!! substr(strip_tags($post->body), 0, 200) !!}</p>
                    <small class="text-muted">Published {{ $post->created_at }}</small>
                </div>

            </li>    
        @empty
            <li>You have not written any posts yet, write one now</li>
        @endforelse

    </ul>
</div>

//CreatePost.php
<?php
namespace App\Http\Livewire;
use App\Post;
use Livewire\Component;
use Illuminate\Support\Str;
class CreatePost extends Component
{
    public $title, $body;
    public $success;
    protected $rules = [
        'title' => 'required|string|max:220',
        'body' => 'required'
    ];

    public function render()
    {
        return view('livewire.create-post')
            ->extends('layouts.app')
            ->section('content');
    }
    public function create(){
        $this->validate();
        Post::create([
            'title' => $this->title,
            'slug' => Str::slug($this->title),
            'body' => $this->body,
            'author_id' => auth()->id()
        ]);

        $this->success = true;
    }
}

W powyższym komponencie tworzymy zmienne publiczne do przechowywania tytułu i treści posta na blogu, a także zmienną wskazującąsuccess, czy tworzenie posta się powiedzie.

W metodzie render() Livewire pozwala nam określić plik układu do wykorzystania do renderowania komponentu i sekcję, w której chcemy go wyświetlić odpowiednio za pomocą extends() metod isection().

Teraz widok szablonu wygląda następująco:Jeśli przejdziesz do przeglądarki do /posts/create, powinieneś zobaczyć wyświetlony formularz tworzenia:

<div class="container">
    @if ($success)
        <div>
            <div class="alert alert-success">
                Post has been created successfully. <a href="{{ url('/home') }}">View all posts</a>
            </div>

        </div>
    @endif

    <form wire:submit.prevent="create">
        <div class="form-group">
            <label for="Post title"&gt;Post title</label>
            <input wire:model="title" type="text" name="title" id="title" class="form-control" placeholder="Title of the post">
            @error('title') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="form-group">
            <label for="Post body">Post Body</label>
            <textarea name="body" id="body" placeholder="Body of post here..." wire:model="body" class="form-control"></textarea>
            @error('body') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div>
            <button class="btn btn-primary" type="submit">Publish</button>
        </div>
    </form>
</div>

Jest to dość podstawowy przykład tego,

Creation Form Display

jak Livewire może być stosowany w prawdziwym świecie.

Wniosek:

Livewire wypełnia lukę między backendem a frontendem. Korzystasz z interaktywności w czasie rzeczywistym bez konieczności samodzielnego pisania dużej ilości kodu JavaScript. Jeśli korzystałeś wcześniej z Vue.js, bardzo łatwo jest dostrzec zalety Livewire.

Livewire nie jest dobrym wyborem dla aplikacji, które są bardzo wymagające po stronie klienta. Ale w sytuacjach, w których potrzebujesz aplikacji renderowanej na serwerze z odrobiną reaktywności, Livewire będzie Ci dobrze służyć.

Ponownie, aplikację, którą zbudowaliśmy w tym samouczku, można znaleźć naGonoHUb.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297