Hòa Nguyễn Coder
Posted on October 8, 2024
Today, I have write a example "Pagination" in Vue CLI 3 + Pinia
The first , we can install library Pinia
yarn add pinia
# or with npm
npm install pinia
Pinia help manager state in Store, we can setup state from Pinia, after then use in component
Okay, the code below, I have setup Store Product + Custom Pagination
// stores/product.ts
import { defineStore } from 'pinia'
import axios from 'axios'
export const useProductStore = defineStore('product', {
state:()=>{
return {
products: [],
perPage: 5,
currentPage: 1,
totalPages: 0
}
},
getters: {
all(state){
return state.products
},
total(state){
return state.totalPages
}
},
actions:{
getProducts(){
axios.get('https://dummyjson.com/products').then((response) => {
console.log("products",response.data.products)
this.totalPages = response.data.products.length / this.perPage
this.pagination(1)
})
},
pagination(page : number){
axios.get('https://dummyjson.com/products/?limit='+this.perPage+'&skip='+((page-1)*this.perPage)+
'&select=title,thumbnail,price,rating,category').then((response) => {
console.log("pagination",response.data.products)
let data = response.data.products;
this.products = data
})
}
}
})
The following below code, I setup state , getters, actions. we can use it in the component
// ProductView.vue
<script>
import { computed } from 'vue'
import { useProductStore } from '../../stores/product'
export default {
name: 'ProductView',
setup() {
const productStore = useProductStore()
// Dispatch fetch products
productStore.getProducts()
// Reactive computed properties
const products = computed(() => productStore.all)
const totalPages = computed(() => productStore.total)
const currentPage = computed(() => productStore.currentPage)
// Hàm thay đổi trang
const changePage = (page) => {
productStore.pagination(page)
productStore.currentPage = page
}
return {
products,
totalPages,
currentPage,
changePage
}
}
}
</script>
We can call state in ProductView.vue
<template>
....
<tbody v-if="products.length>0">
<tr v-for="product in products" key="product.id">
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<div class="flex">
<div class="flex-shrink-0 w-16 h-16">
<img
class="w-full h-full "
v-bind:src="product.thumbnail"
alt=""
/>
</div>
<div class="ml-3">
<p class="text-gray-900 whitespace-no-wrap">
{{ product.title }}
</p>
<p class="text-gray-600 whitespace-no-wrap">SKU : {{ product.sku }}</p>
</div>
</div>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<p class="text-gray-900 whitespace-no-wrap">${{ product.price }}</p>
<p class="text-gray-600 whitespace-no-wrap">USD</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<p class="text-gray-900 whitespace-no-wrap">{{ product.rating }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<span
class="relative inline-block px-3 py-1 font-semibold text-green-900 leading-tight"
>
<span
aria-hidden
class="absolute inset-0 bg-green-200 opacity-50 rounded-full"
></span>
<span class="relative">{{ product.category }}</span>
</span>
</td>
<td
class="px-5 py-5 border-b border-gray-200 bg-white text-sm text-right"
>
<button
type="button"
class="inline-block text-gray-500 hover:text-gray-700"
>
<svg
class="inline-block h-6 w-6 fill-current"
viewBox="0 0 24 24"
>
<path
d="M12 6a2 2 0 110-4 2 2 0 010 4zm0 8a2 2 0 110-4 2 2 0 010 4zm-2 6a2 2 0 104 0 2 2 0 00-4 0z"
/>
</svg>
</button>
</td>
</tr>
</tbody>
<!-- list pagination -->
<nav v-if="totalPages>0">
<ul class="pagination flex flex-wrap gap-2">
<li
v-for="page in totalPages"
:key="page"
class="page-item bg-gray-500 text-white w-8 h-8 flex items-center justify-center rounded-md"
:class="{ 'bg-green-700 text-white': currentPage === page }"
>
<button
class="page-link"
@click="changePage(page)"
>
{{ page }}
</button>
</li>
</ul>
</nav>
</template>
Demo:
💖 💪 🙅 🚩
Hòa Nguyễn Coder
Posted on October 8, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.