keyboard_tabSkip to content
listVue Firebase Masterclass

ทำหน้าแสดงผลหลัก

สารบัญ

เริ่มต้นทำ store product.js

  • เพื่อเป็นแหล่งข้อมูลนำ product มาใช้
javascript
import { defineStore } from 'pinia'

export const useUserProductStore = defineStore('user-product', {
  state: () => ({
    list: [{
      name: 'test',
      imageUrl: 'https://fastly.picsum.photos/id/849/200/200.jpg?hmac=LwsdGn2endKvoLY10FPqtfqKYCVMbPEp5J6S_tUN1Yg',
      quantity: 10,
      about: 'testt',
      status: 'open',
      price: 100,
    }],
    loaded: false
  })
})

ทำ HomeView.vue

  • แสดงหน้า Home
  • ทำ component ProductList.vue เพื่อให้เรียกใช้ได้จากหน้า Search ด้วย (style จะได้เหมือนกัน)

เริ่มต้นสร้าง ProductList.vue ก่อน

html
<script setup>
import { defineProps } from 'vue'

defineProps({
  products: Array,
  addToCart: Function
})
</script>

<template>
  <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 m-10">
    <div v-for="(product, index) in products" class="card w-full bg-base-100 shadow-xl" :key="index">
      <figure>
        <img class="w-full" :src="product.imageUrl" alt="Shoes" />
      </figure>
      <div class="card-body">
        <h2 class="card-title">{{ product.name }}</h2>
        <p>{{ product.about }}</p>
        <div class="card-actions justify-end">
          <button @click="addToCart(product)" class="btn btn-primary">Buy Now</button>
        </div>
      </div>
    </div>
  </div>
</template>

หลังจากนั้นที่หน้า HomeView.vue เราจะเพิ่มการเรียก component ProductList.vue เพื่อแสดงผล Product

html
<script setup>
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'

import { useUserProductStore } from '@/stores/user/product'

import UserLayout from '@/layouts/UserLayout.vue'
import ProductList from '@/components/ProductList.vue'

const userProductStore = useUserProductStore()

const router = useRouter()

onMounted(() => {
  userProductStore.loadProduct()
})

</script>

<template>
  <UserLayout>
    <div class="hero min-h-screen bg-base-200">
      <div class="hero-content text-center">
        <div class="max-w-md">
          <h1 class="text-5xl font-bold">Hello to shop</h1>
          <p class="py-6">Trust your intuition</p>
        </div>
      </div>
    </div>
    <ProductList
      :products="userProductStore.list"
    >
    </ProductList>
  </UserLayout>
</template>

ผลลัพธ์ intro-01

ทำ SearchView.vue

แสดง Search ออกมาได้โดยการใส่ข้อมูลที่ต้องการ Search ด้านบน Navbar กด Enter แล้วไปยังหน้า search ได้

สิ่งที่เราจะทำ

  • เพิ่ม filterProduct ใน product.js เพื่อเก็บ logic การจัดการ filterProducts ไว้ใน store ที่เดียว
  • เพิ่ม code SearchView.vue สำหรับดึงข้อมูล filterProducts จาก store มาใช้โดย reused จาก ProductList component ที่สร้างก่อนหน้านี้ พร้อมกับเพิ่ม code รับผ่าน param query ไปผ่าน router /search?q=<search text>
  • ที่ Navbar (UserLayout) เพิ่ม event สำหรับการส่งข้อมูลจาก Navbar ไปยังหน้า search ผ่าน query param

let's code

  • ที่ product.js เพิ่ม filterProducts มาใน actions เพื่อนำผลลัพธ์มา filter ได้
javascript
import { defineStore } from 'pinia'

export const useUserProductStore = defineStore('user-product', {
  state: () => ({ ... }),
  actions: {
    filterProducts (searchName) {
      return this.list.filter(product => product.name.includes(searchName))
    }
  }
})
  • หลังจากนั้นที่ SearchView.vue
html
<script setup>
import { ref, watch, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import ProductList from '@/components/ProductList.vue'
import UserLayout from '@/layouts/UserLayout.vue'

import { useUserProductStore } from '@/stores/user/product'

const userProductStore = useUserProductStore()

const route = useRoute()
const router = useRouter()

const searchText = ref('')
const filterProducts = ref([])

watch(() => route.query.q, (newSearchText) => {
  searchText.value = newSearchText
  filterProducts.value = userProductStore.filterProducts(searchText.value)
}, { immediate: true })
</script>

<template>
  <UserLayout>
    <div class="m-10">
      <h1 class="text-3xl">Search: <span class="font-bold">{{ searchText }}</span></h1>
    </div>
    <div v-if="filterProducts.length > 0">
      <ProductList
        :products="filterProducts"
      >
      </ProductList>
    </div>
    <div class="m-10" v-else>
      <div class="text-center text-3xl">Product not found</div>
    </div>
  </UserLayout>
</template>
  • สุดท้ายเพิ่ม Event ที่ layout/UserLayout.vue
html
<script setup>
  //...
  // สร้าง function ดักตาม Enter
  const handleEnter = (event) => {
    if (event.key === 'Enter') {
      router.push({
        name: 'search',
        query: {
          q: searchText.value
        }
      })
    }
  }
</script>
<template>
  <!-- code ก่อนหน้า -->
    <div class="flex-none">
      <div class="form-control">
        <input
          type="text"
          v-model="searchText"
          placeholder="Search"
          class="input input-bordered w-24 md:w-auto"
          @keyup="handleEnter" 
        /> <!-- เพิ่ม handleEnter ตรง keyup -->
        <!-- code ตรง profile-->
      </div>
    </div>
    <!-- code หลัง navbar -->
</template>

ผลลัพธ์ home-02