Build a Shopping Cart Using Vue js 3 Composition API Laravel 11 & Stripe Payment Gateway Part 4
In the fourth part of this tutorial, we will fetch and display all the products, and add the store with the actions so we can add update, and remove products from the cart.
Create the store
Let's create the store in the image we have seen in the previous tutorial we have a folder called store inside we have a file 'useCartStore.js' inside add the code below:
import { defineStore } from 'pinia'
import { useToast } from "vue-toastification"
const toast = useToast()
export const useCartStore = defineStore('shopping', {
state: () => {
return {
cartItems : []
}
},
getters: {
countCartItems(){
return this.cartItems.length;
},
getCartItems(){
return this.cartItems;
}
},
actions: {
addToCart(item) {
let index = this.cartItems.findIndex(product => product.id === item.id);
if(index !== -1) {
this.cartItems[index].quantity += 1;
toast.success("Product quantity increased", {
timeout: 3000
})
}else {
item.quantity = 1;
this.cartItems.push(item);
toast.success("Product added to the cart", {
timeout: 3000
})
}
},
incrementQ(item) {
let index = this.cartItems.findIndex(product => product.id === item.id);
if(index !== -1) {
this.cartItems[index].quantity += 1;
toast.success("Product quantity increased", {
timeout: 3000
})
}
},
decrementQ(item) {
let index = this.cartItems.findIndex(product => product.id === item.id);
if(index !== -1) {
this.cartItems[index].quantity -= 1;
if(this.cartItems[index].quantity === 0){
this.cartItems = this.cartItems.filter(product => product.id !== item.id);
}
toast.success("Product quantity decreased", {
timeout: 3000
})
}
},
removeFromCart(item) {
this.cartItems = this.cartItems.filter(product => product.id !== item.id);
toast.success("Product removed from the cart", {
timeout: 3000
})
}
},
})
Add the home component
Inside the home component, we fetch all the products from the backend and send them to the product list component.
<template>
<ProductList :products="data.products" />
</template>
<script setup>
import ProductList from "./products/ProductList.vue"
import { onMounted, reactive } from "vue"
import axios from "axios"
const data = reactive({
products: []
})
const fetchAllProducts = async () => {
try {
const response = await axios.get('https://darija-coding.com/api/products')
data.products = response.data.data
} catch (error) {
console.log(error)
}
}
onMounted(() => fetchAllProducts())
</script>
<style>
</style>
Add the product list component
Inside the product list component, we receive the products, loop through, and send each product to the product list item component.
<template>
<div className='row my-4'>
<ProductListItem v-for="product in products"
:key="product.id" :product="product" />
</div>
</template>
<script setup>
import ProductListItem from './ProductListItem.vue'
const props = defineProps({
products: {
type: Array,
required: true,
}
});
</script>
<style>
</style>
Add the product list item component
Inside the product list item component, we receive the product, display the details, and add the add-to-cart functionality.
<template>
<div class="col-md-4 mb-2">
<div class="card h-100">
<img :src="product.product_image" class="card-img-top" alt="..." />
<div class="card-body">
<h5 class="card-title">{{product.product_name}}</h5>
<p class="card-text">{{product.product_desc}}</p>
<p><span class="fw-bold text-danger">${{product.product_price}}</span></p>
<button
@click="store.addToCart(product)"
class="btn btn-primary">
<i class="bi bi-cart-check"></i> add to cart
</button>
</div>
</div>
</div>
</template>
<script setup>
import { useCartStore } from '../../store/useCartStore'
//get props
const props = defineProps({
product: {
type: Object,
required: true
}
});
//get store
const store = useCartStore();
</script>
<style>
</style>