iT邦幫忙

2021 iThome 鐵人賽

DAY 23
1
Modern Web

Laravel Livewire:不用 Vue 跟 jQuery 居然也能讓 Laravel 的畫面動起來 ?!系列 第 23

Day 22.5 | Livewire 實作 購物網站: 建立資料表

本來預計都寫在 Day22 的,但是加上本篇內容後會讓一天的篇幅太長,且考慮到有些夥伴可能沒有建立資料表的需求。因此資料建立方面獨立開一篇來做解說,之後的內容接續本篇 Day 22 | Livewire 實作 購物網站(一): 建立商品列表

建立資料表

首先要來規劃資料表,以下先設想幾個欄位:

欄位名稱 型態 允許空值 說明
name varchar x 商品名稱
price integer x 商品價格
slogan varchar v 廣告標語
specs text v 商品規格
content text v 商品內容
image_url varchar v 圖片網址

大致想好後透過 migration 來建立資料表:

php artisan make:migration create_goods_table

透過指令建立遷移檔後可以到 /database/migrations 下找到剛剛新增的檔案,檔名類似這樣 2021_09_24_161700_create_goods_table.php 前面會帶有建立的時間戳,接著照剛剛個規劃來編輯遷移檔的內容:

...

public function up()
{
    Schema::create('goods', function (Blueprint $table) {
        $table->id();
        $table->string('name')->comment('商品名稱');
        $table->integer('price')->comment('商品價格');
        $table->string('slogan')->nullable()->comment('廣告標語');
        $table->text('specs')->nullable()->comment('商品規格');
        $table->text('content')->nullable()->comment('商品內容');
        $table->string('image_url')->nullable()->comment('商品圖片網址');
        $table->timestamps();
    });
}

...   

編輯完成後再透過指令就能靠遷移檔來開資料表啦!

php artisan migrate

別忘記建立 Model

php artisan make:model Good

Model 中要新增可被填寫的資料欄位:

class Good extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'price',
        'slogan',
        'specs',
        'content',
        'image_url',
    ];
}


建立資料

有了資料表就差資料了,在 Laravel 我們能很方便的透過 Factory 來建立大量資料,但這樣會增加學習成本,平時不做測試也不會用到,因此這邊就不教各位怎麼用 Factory 加 Faker 來建立假的資料,有興趣的夥伴可以自行 Google。

還是照往常一樣,我們用 Livewire 能很快的刻出一個表單輸入。這裡就順便在練個手,熟悉一下操作吧!

php artisan make:livewire Shopping/CreateItem

記得加到 routes 中才找得到頁面哦

Route::get('/shopping-create', App\Http\Livewire\Shopping\CreateItem::class);

因為知道後端要哪些東西了,這次就從後端先做:

<?php

namespace App\Http\Livewire\Shopping;

use Livewire\Component;
use App\Models\Good;

class CreateItem extends Component
{
    // 宣告到時候 Input 會用到的欄位
    public $name;
    public $price;
    public $slogan;
    public $specs;
    public $content;

    // 驗證必填欄位
    protected $rules = [
        'name' => 'required|min:3',
        'price' => 'required|integer',
    ];

    public function render()
    {
        return view('livewire.shopping.create-item');
    }

    //
    // 建立商品
    public function createItem()
    {
        $this->validate();

        Good::create([
            'name' => $this->name,
            'price' => $this->price,
            'slogan' => $this->slogan,
            'specs' => $this->specs,
            'content' => $this->content,
        ]);

        // 完成後清除
        $this->name = '';
        $this->price = '';
        $this->slogan = '';
        $this->specs = '';
        $this->content = '';

        // 通知頁面已新增
        $this->emit('created');
    }
}

之後就是前端頁面啦

<div class="mx-2 mt-2 flex justify-center">
    <div class="ui form my-5 w-96 shadow-xl p-5">
        <h4 class="ui dividing header mb-2">建立商品</h4>
        <div class="field">
            <label>商品名稱</label>
            <input type="text" wire:model.defer="name">
            @error('name')<span class="text-red-500">{{ $message }}</span>@enderror
        </div>
        <div class="field">
            <label>價格</label>
            <input type="text" wire:model.defer="price">
            @error('price')<span class="text-red-500">{{ $message }}</span>@enderror
        </div>
        <div class="field">
            <label>廣告標語</label>
            <input type="text" wire:model.defer="slogan">
        </div>
        <div class="field">
            <label>規格</label>
            <textarea rows="4" wire:model.defer="specs"></textarea>
        </div>
        <div class="field">
            <label>內容</label>
            <textarea rows="4" wire:model.defer="content"></textarea>
        </div>
        <div class="field">
            <label>圖片網址</label>
            <input type="text" wire:model.defer="image_url">
        </div>
        <div class="text-center">
            <button class="ui button" wire:click="createItem">新增商品</button>
        </div>
    </div>
</div>

<!-- 接收來自後端的 $emit('created') -->
@section('scripts')
<script>
    Livewire.on('created', () => {
        alert('商品建立完成!')
    })
</script>
@endsection

如果要加上上傳圖片的功能會更複雜,這邊用直接填入圖片網址代替,至於圖片來源可以直接從免費圖庫複製網址來當假資料使用!

https://ithelp.ithome.com.tw/upload/images/20210925/20111805rpJghBqt1f.png

這麼一來就能新增商品了呢!


上一篇
Day 22 | Livewire 實作 購物網站(一): 建立商品列表
下一篇
Day23 | Livewire 實作 購物網站(二): 建立商品細節頁面
系列文
Laravel Livewire:不用 Vue 跟 jQuery 居然也能讓 Laravel 的畫面動起來 ?!34

尚未有邦友留言

立即登入留言