Categories
Vue 3 Projects

Create a Shopping Cart with Vue 3 and JavaScript

Spread the love

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a shopping cart app with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create shopping-cart

and select all the default options to create the project.

We also need the Vue Router package to let us navigate to different pages in the app.

To do this, we run:

npm i vue-router@next

Create the Shopping Cart

The first step for creating the shopping cart is to create the view files.

We create the views folder in the src folder.

Then inside it, we add the Cart.vue and Store.vue files to create the store page which we can browser.

Cart.vue has the cart page.

Then in main.js , we add the Vue Router into our app by writing:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import Cart from "./views/Cart";
import Store from "./views/Store";
import { createRouter, createWebHashHistory } from "vue-router";

const routes = [
  { path: "/", component: Store },
  { path: "/cart", component: Cart }
];

const router = createRouter({
  history: createWebHashHistory(),
  routes
});

const app = createApp(App);
app.use(router);
app.mount("#app");

We import the view component files we created earlier.

Then we add them to the routes array.

Next, we call createRouter to create the router object.

We add the routes object, we created earlier inside the argument object.

createWebHashHistory makes Vue Router add a # sign between the first segment and the other segments of the URL.

And then we call app.use with router to add the router.

To create a simple store page, we go into Store.vue and write:

<template>
  <div>
    <h1>Store</h1>
    <div v-for="item of items" :key="item.id">
      <p>{{ item.name }}</p>
      <img :src="item.imageUrl" />
      <button @click="removeFromCart(item.id)" v-if="isInCart(item.id)">
        remove from cart
      </button>
      <button @click="addToCart(item.id)" v-else>add to cart</button>
    </div>
    <button @click="$router.push('/cart')">check out</button>
  </div>
</template>

<script>
const items = Object.freeze([
  {
    id: 1,
    imageUrl: "grape.jpg",
    name: "grape",
  },
  {
    id: 2,
    imageUrl: "orange.jpg",
    name: "orange",
  },
  {
    id: 3,
    imageUrl: "apple.jpg",
    name: "apple",
  },
]);

export default {
  name: "Store",
  data() {
    return {
      items,
      cart: [],
    };
  },
  methods: {
    isInCart(itemId) {
      if (!localStorage.getItem("cart")) {
        localStorage.setItem("cart", JSON.stringify([]));
      }
      const cartItem = this.cart.find(({ id }) => id === itemId);
      return Boolean(cartItem);
    },
    addToCart(itemId) {
      const item = this.items.find(({ id }) => id === itemId);
      if (!localStorage.getItem("cart")) {
        localStorage.setItem("cart", JSON.stringify([]));
      }
      const cartItems = JSON.parse(localStorage.getItem("cart"));
      cartItems.push(item);
      localStorage.setItem("cart", JSON.stringify(cartItems));
      this.cart = JSON.parse(localStorage.getItem("cart"));
    },
    removeFromCart(itemId) {
      const cartItems = JSON.parse(localStorage.getItem("cart"));
      const index = cartItems.findIndex(({ id }) => id === itemId);
      cartItems.splice(index, 1);
      localStorage.setItem("cart", JSON.stringify(cartItems));
      this.cart = JSON.parse(localStorage.getItem("cart"));
    },
  },
};
</script>

We render the store items with v-for .

We display the remove from cart button if the item is already added top the cart.

And we show the add to cart button otherwise.

The check is done by the isInCart method, which gets the cart items from the this.cart reactive property and check if find returns anything given the itemId .

addToCart adds the item to the cart entry in local storage, which is an array that we create if it doesn’t exist.

After that, we update the this.cart reactive property with the latest value from local storage.

removeFromCart finds the index from the cart items from local storage by the itemId with findIndex .

Then we call splice to remove the item by the index .

And then we call setItem to update the cart with the latest items in the cart.

And we update this.cart with the latest values form local storage.

items have the store items.

The checkout button calls $router.push with '/cart' to go the cart page.

To add the content for the cart page, we write the following in Cart.vue:

Cart.vue

<template>
  <div>
    <h1>Cart</h1>
    <div v-for="(c, index) of cart" :key="c.id">
      <p>{{ c.name }}</p>
      <img :src="c.imageUrl" />
      <button @click="removeFromCart(index)">remove from cart</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "Cart",
  data() {
    return {
      cart: [],
    };
  },
  methods: {
    removeFromCart(itemId) {
      const cartItems = JSON.parse(localStorage.getItem("cart"));
      const index = cartItems.findIndex(({ id }) => id === itemId);
      cartItems.splice(index, 1);
      localStorage.setItem("cart", JSON.stringify(cartItems));
      this.cart = JSON.parse(localStorage.getItem("cart"));
    },
    getCart() {
      if (!localStorage.getItem("cart")) {
        localStorage.setItem("cart", JSON.stringify([]));
      }
      this.cart = JSON.parse(localStorage.getItem("cart"));
    },
  },
  beforeMount() {
    this.getCart();
  },
};
</script>

We have the same remvoeFromCart method as in Store.vue .

getCart gets the cart item from local storage and then set the returned value as the value of the this.cart reactive property.

And then we render the this.cart entries with v-for in the template.

We have the remove from cart button to remove the item with removeFromCart .

Finally, in App.vue , we write:

<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

<style>
img {
  width: 200px;
  height: 200px;
}
</style>

to add the router-view so we can see the route that Vue Router renders.

We also shrink the images to 200px by 200px with the style tag.

Conclusion

We can create a simple shopping cart easily with Vue 3 and JavaScript.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *