ทำหน้าแสดงผลหลัก
เริ่มต้นทำ store product.js
- เพื่อเป็นแหล่งข้อมูลนำ product มาใช้
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
ก่อน
<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
<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>
ผลลัพธ์
ทำ 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 ได้
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
<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
<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>
ผลลัพธ์