keyboard_tabSkip to content
listVue Firebase Masterclass

ทำหน้า Checkout / Success

สารบัญ

ทำ CheckoutView เพิ่ม

  • เพิ่ม UI หน้า checkout โดยแสดง
    • ฝั่งซ้าย เป็น form กรอกข้อมูลจัดส่งของ user
    • ฝั่งขวา เป็น ข้อมูลสรุปทั้งหมดของตะกร้าสินค้า
  • ดึงข้อมูลตะกร้าผ่าน store store/user/cart.js เข้ามา โดยที่ cart store เพิ่ม actions 2 อันเอาไว้คือ
    • checkout (checkoutData) สำหรับนำข้อมูล checkout ไปเก็บไว้ใน localstorage
    • loadCheckout () สำหรับดึงข้อมูล checkout ออกมาจาก localstorage (เพื่อใช้ในหน้าของ Success)
  • เพิ่ม state checkout: {} สำหรับเก็บข้อมูล checkout เอาไว้ในในหน้า Success
  • เมื่อกด "ชำระเงิน" = ให้ส่งข้อมูลเข้า checkout และ redirect ไปหน้า Success (ทำการ mock Success ไว้ก่อน)

ที่ store/user/cart.js

javascript
import { defineStore } from 'pinia'

export const useUserCartStore = defineStore('user-cart', {
  state: () => ({
    items: [],
    checkout: {} // เพิ่มเข้ามา
  })
  actions: {
    /* ... */
    checkout (checkoutData) {
      let checkout = {
        ...checkoutData,
        totalPrice: this.summaryPrice,
        paymentMethod: 'Credit Card',
        createdAt: (new Date()).toLocaleString(),
        orderNumber: `AA${(Math.floor(Math.random() * 900000) + 100000).toString()}`,
        products: this.items
      }
      localStorage.setItem('checkout-data', JSON.stringify(checkout))
    },
    loadCheckout () {
      let checkoutData = localStorage.getItem('checkout-data')
      if (checkoutData) {
        this.checkout = JSON.parse(checkoutData)
      }
    }
  }
})

ที่ CheckoutView

html
<script setup>
import UserLayout from '@/layouts/UserLayout.vue'

import { computed, reactive } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import { useUserCartStore } from '@/stores/user/cart'

const checkoutForm = [
  {
    name: 'Email Address',
    field: 'email'
  },
  {
    name: 'Name',
    field: 'name'
  },
  {
    name: 'Address',
    field: 'address'
  },
  {
    name: 'Note',
    field: 'note'
  }
]

const userCartStore = useUserCartStore()
const userCheckoutData = reactive({})
const router = useRouter()

const checkout = () => {
  // submit checkout data
  userCartStore.checkout(userCheckoutData)
  router.push({ name: 'success' })
}
</script>

<template>
  <UserLayout>
    <div class="container mx-auto my-4">
      <h1 class="text-4xl mb-4">Checkout</h1>
      <div class="flex">
        <section class="flex-auto w-64 bg-base-200">
          <div class="px-8 py-2">
            <div
              v-for="form in checkoutForm"
              class="form-control w-full"
            >
              <label class="label">
                <span class="label-text">{{ form.name }}</span>
              </label>

              <textarea
                v-if="form.field === 'address'"
                class="textarea textarea-bordered h-24"
                placeholder="Address"
                v-model="userCheckoutData[form.field]"
              ></textarea>
              <input
                v-else
                type="text"
                placeholder="Type here"
                class="input input-bordered input-sm w-full"
                v-model="userCheckoutData[form.field]"
              />
            </div>
            <button class="btn btn-primary w-full mt-4" @click="checkout()">
              ชำระเงิน
            </button>
          </div>
        </section>
        <section class="flex-auto w-32 bg-slate-200">
          <div class="px-8">
            <ul>
              <li v-for="(item, index) in userCartStore.items" class="px-2 flex py-6" :key="index">
                <img
                  class="w-40 object-cover object-center"
                  :src="item.imageUrl"
                />
                <div class="flex flex-col justify-between ml-4">
                  <div>
                    <div>{{ item.name }}</div>
                    <div>จำนวน: {{ item.quantity }}</div>
                  </div>
                  <div class="flex mt-2">
                    <RouterLink :to="{ name: 'cart' }">
                      <button>Edit</button>
                    </RouterLink>
                  </div>
                </div>
              </li>
            </ul>
            <div class="divider"></div>
            <div class="mb-4">
              <h2 class="text-2xl">Order summary</h2>
              <div class="mt-4 m-0">
                <div class="flex align-middle justify-between mb-2">
                  <div class="font-bold">ราคาสินค้าทั้งหมด</div>
                  <div>{{ userCartStore.summaryPrice }}</div>
                </div>
                <div class="flex align-middle justify-between mb-2">
                  <div class="font-bold">ค่าส่ง</div>
                  <div>0</div>
                </div>
                <div class="divider"></div>
                <div class="flex align-middle justify-between mb-2">
                  <div class="font-bold">ราคาทั้งสิ้น</div>
                  <div>{{ userCartStore.summaryPrice }}</div>
                </div>
              </div>
            </div>
          </div>
        </section>
      </div>
    </div>
  </UserLayout>
</template>

ผลลัพธ์ที่ได้ checkout-01

เพิ่ม Action ที่เข้าได้จาก CartView

  • เพิ่ม action ในหน้า Cart โดยหลังจากกดปุ่ม "ชำระเงิน" ที่หน้า ตะกร้าสินค้า ให้ redirect มายังหน้า Checkout
html
<template>
  <!-- เพิ่มแค่นี้ที่ template เลย-->
  <RouterLink to="/checkout" class="btn btn-primary w-full">
      ชำระเงิน
    </RouterLink>
</template>

ผลลัพธ์ที่ได้ checkout-03

ทำ SuccessView

  • ทำหน้า UI Success page (เป็นหน้าที่ redirect มาจาก Checkout อีกที) โดย
    • มีแสดงข้อมูล Order (ที่ generate ผ่าน function checkout()) ออกมา
    • มีแสดงข้อมูล Product ในตะกร้าทั้งหมดว่ามีอะไรบ้าง
    • มีแสดงยอดรวมของตะกร้าทั้งหมด
  • ดึงข้อมูลมาแสดงจาก cart store (โดยดึงส่วน checkout ออกมา)

ผลลัพธ์ที่ได้ checkout-02