2️⃣

Livewire 3のクイックスタートを拡張してみる 2

2024/05/21に公開

目的等

前回の記事の続きです。↓
https://zenn.dev/gedatsu/articles/ba05254070538d

前回までは


のような状態になりました。

今回の拡張後

やったこと

  • livewireコンポーネントの初期パラメータ設定
  • 別のlivewireコンポーネントとの連携
  • 画面タイトルの設定
  • レイアウトファイルの変更

手順

Cartコンポーネント作成

前回のCounterコンポーネントとは別コンポーネントを作成していきます。

php artisan make:livewire cart
app/Livewire/Cart.php
use Livewire\Attributes\On;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Title('カート')]
class Cart extends Component
{
    public $items = [];
    public $price = 0;

    public function mount()
    {
        $this->items = [
            [
                'name' => 'りんご',
                'price' => '300',
            ],
            [
                'name' => 'みかん',
                'price' => '100',
            ],
            [
                'name' => 'ぶどう',
                'price' => '450',
            ],
        ];
    }

    #[On('addPrice')]
    public function addPrice($price)
    {
        $this->price += $price;
    }

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

app/resources/views/livewire/cart.blade.php
<div>
    <div class="grid grid-cols-3 gap-2">
        @foreach($items as $key => $item)
            <livewire:counter :key="$key" :name="$item['name']" :price="$item['price']" />
        @endforeach
    </div>
    <div class="w-full fixed bottom-0 h-24 bg-gray-100">
        <div class="flex h-full items-center justify-center text-2xl">
            合計価格:{{number_format($price)}}</div>
    </div>
</div>

mountメソッドを利用することで、初期データを入れています。
こちらの配列をblade内でループさせて、前回作ったCounterコンポーネントを呼び出しています。
呼び出すパラメータとして、keynamepriceがあり、namepriceはCounterコンポーネントに追加する必要があります。

Counterコンポーネントの変更

app/Livewire/Counter.php
use Livewire\Component;

class Counter extends Component
{
+    public $name;
+    public $price;
-    public $count = 1;
+    public $count = 0;

    public function increment()
    {
        $this->count++;
+       $this->dispatch('addPrice', $this->price);
    }

    public function decrement()
    {
        $this->count--;
+        $this->dispatch('addPrice', -$this->price);
    }


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

app/resources/views/livewire/counter.blade.php
<div class="border p-4 w-64 text-center mx-auto">
    <div class="text-xl pb-5">
        {{ $name }}{{$price}}</div>
    @if ($count > 0)
        <div class="text-sm flex border rounded">
            <x-buttons.button1 wire:click="decrement">
                @if ($count == 1)
                    <x-icons.trash class=""/>
                @else
                    <x-icons.minus/>
                @endif
            </x-buttons.button1>

            <input x-mask="99" class="text-4xl object-center w-full text-center" wire:model="count"/>

            <x-buttons.button1 wire:click="increment">
                <x-icons.plus/>
            </x-buttons.button1>
        </div>
    @else
        <x-buttons.button1 wire:click="increment">
            追加
        </x-buttons.button1>
    @endif
</div>

namepriceの用意と表示を行いました。また、若干ボタンと数値の位置関係も変えてみました。

レイアウトファイルの変更

前回Counterコンポーネントで指定していた中央寄せをこっちにいれちゃいましょう。

app/resouces/views/components/layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        @vite('resources/css/app.css')

        <title>{{ $title ?? 'Page Title' }}</title>
    </head>
    <body>
        <div class="h-screen place-content-center">
            {{ $slot }}
        </div>
    </body>
</html>

ルート定義

作成したコンポーネントのルーティングを定義したら完成!

routes/web.php
Route::get('/cart', Cart::class);

まとめ

いい感じにカートっぽくなってきました〜。次回はDBとの連携等を行っていこうかな。
※ 直接数字入力したときに合計価格がずれていたので次回に直していきます。

Discussion