Day 24 | Livewire 实作 购物网站(三): 加入购物车

实作了商品细节页之後就要把商品加进购物车啦,今天会把要买的东西存进 Laravel 的 Session 中。那就来看看怎麽做吧!

今日目标:加入购物车

ㄧ、刻一个购物车按钮

很多购物网站在最上方的导航列都会有一个购物车按钮让你点进去看到底在购物车中放了什麽东西,我们目前还没有所以就先刻一个!顺便让他显示购物车中有多少项目!

https://ithelp.ithome.com.tw/upload/images/20210927/20111805H38AZDzHQR.png

这边稍微修改一下昨天最後做的导航列,一样在 index.blade.php 中。

    <div class="h-15 bg-gray-300 p-2 -mx-2 -mt-2 mb-10 flex justify-between">
        <div>
            @if($selectedItem)
                <button class="bg-gray-600 text-white px-5 py-2 h-10 rounded" wire:click="cleanItem">返回列表</button>
            @endif
        </div>
        
        <button class="bg-gray-600 text-white px-5 py-2 h-10 rounded">
            <span>购物车</span>
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cart inline" viewBox="0 0 16 16">
                <path d="M0 1.5A.5.5 0 0 1 .5 1H2a.5.5 0 0 1 .485.379L2.89 3H14.5a.5.5 0 0 1 .491.592l-1.5 8A.5.5 0 0 1 13 12H4a.5.5 0 0 1-.491-.408L2.01 3.607 1.61 2H.5a.5.5 0 0 1-.5-.5zM3.102 4l1.313 7h8.17l1.313-7H3.102zM5 12a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm7 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm-7 1a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm7 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
            </svg>
            <div class="bg-red-500 text-white font-extrabold rounded-lg inline px-1">5</div>
        </button>
    </div>

https://ithelp.ithome.com.tw/upload/images/20210927/201118059hnQr498RW.png

因为只会有两个按钮,所以偷懒了一下用左右对齐的排版 flex justify-between 方式来做!

二、在点击「加入购物车」按钮时把它塞进 Session 中

这时我们要回到商品细节页 item-detail.blade.php 中,去实作按钮的功能,让他按了能触发後端的 Function:

<button class="..." wire:click="addToCart">加入购物车</button>

当然别忘记後端,为了之後在显示时不用逐一去拉资料库的资料,因此直接整理一下显示购物车时会用到的资料然後直接存入 Session 中。并发一个 $emit 好让主画面能够知道 Session 有被更新过。

注:这是懒散的做法,严谨一点的话只能存 id 并在显示列表时所有的商品资料都从资料库拿。

public function addToCart()
{
    $item = array(
        'id' => $this->item->id,
        'name' => $this->item->name,
        'image_url' => $this->item->image_url,
        'price' => $this->item->price,
    );
    
    session()->push('cart', $item);
    
    // 推送事件,让主画面能更新 Session
    $this->emit('addToCart');
}

三、回头修改主画面,让购物车旁的数字能显示即时的数量

刚刚刻画面时我们暂且放了一个数字5,现在就可以做成动态的了!

首先在後端宣告一个 $cart 变数来存目前购物车中的数量,之後再宣告一个函式去拿 Session 的值。别忘了刚刚做的 $emit 需要一个 $listeners 来做监听并指派到对应的 Function。

public $cart;


protected $listeners = [
    'selectItem',
    'addToCart' => 'getCart',
];

public function getCart()
{
    $cart = session()->get('cart');
    if ($cart) {
        $this->cart = count($cart);
    }
}

为了在重新整理後也能立刻拿到购物车的数量,因此也要在渲染时呼叫 getCart()

public function render()
{
    
    $this->getCart();

    return view('livewire.shopping.index', [
        'list' => Good::all(),
    ]);
}

之後到前端页面把静态资料替换成 {{ $cart }} ,之後只要按下加入购物车就会让购物车的数字自己往上加啦!

https://ithelp.ithome.com.tw/upload/images/20210927/20111805PBNgwSW91f.png

一样附上包含今天内容的 DEMO页面


<<:  全端入门Day27_後端程序撰写之Golang

>>:  D17- 用 Swift 和公开资讯,打造投资理财的 Apps { 移动平均线(MA线)分析 }

[Lesson28] Kotlin - Generics

泛型就是参数化类型,将类别参数化。让你在定义类别、方法、介面时先不用决定型别,等到要实体化时再决定型...

[Day 18] 第一主餐 pt.10-中文资料存料至文中,django如何存取中文

前一篇我们把资料库修改完成了 今天我们就要来把BeautifulSoup的中文资料送过去了 由於昨天...

CSS微动画 - 不知道要吃什麽?Slot帮你选吧

Q: 网路上已经很多可以用的随机选择器了耶... A: 拉霸的用途很多,看你怎麽用罗~ 已经连续N...

爬取多个页面

这次是要一次爬取多个页面的资料,延续抓取漫画资料的程序码。因为我知道每个漫画的路由後面都是编号,所以...

[Day 23] Reactive Programming - Spring WebFlux(Handler)

前言 经过上一个范例的练习,也大致上的知道相较於原本Spring MVC annotation-ba...