Building an E-Commerce app with Vue.js, Vuex & Axios


Ecommerce web applications offer a whole range of new opportunities to business; it helps businesses reduce the costs and can do with fewer overheads & fewer Risks; e-commerce is more comfortable & more Convenient.

Most of the performance optimization for e-commerce web applications are front-end related, So, the use of a prominent framework, for example, Vue; a front-end centric, often preferred for its straightforwardness.

Vue is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
Vue is a Simple, minimal core with an incrementally adoptable stack that can handle apps of any scale. Vue is designed from the ground up to be incrementally adoptable.

With Vue.js, we can write the same JavaScript code providing the same functionality in a much simpler way & more comfortable to read and understand.

In this tutorial, we will build an e-commerce site using Vue.js, with the following features:

  • Get products from the API
  • List the products from the API
  • Details Of The Product
  • Basic cart management
  • Basic user Authentication
  • Add products to the cart
  • A Checkout page

Furthermore, in creating the e-commerce site, we will use Vuex, Vue Router, and Axios. Also, we will show a primary method for handling authentication and cart management in this application.

Before we kick off

Learn Vue.js and modern, cutting-edge front-end technologies from core-team members and industry experts with our premium tutorials and video courses on VueSchool.io.

Click here to Browse all Courses on VueSchool.io

We’ll end up with something like this:

Vue E-Commerce

Prerequisites

In the course of building this application, we would be using Vuex to manage our application state,
Vue router For navigation and Axios to fetch data from the API.

Sequel to the preceding, we should possess a basic knowledge of JavaScript and Vue to aid easy comprehension of the steps to be followed in this article.

We will also need Node.js for a Vue setup, so download and install it if you haven’t already.

Step 1 – Setting up the Vue project

Now let’s start by installing Vue CLI into our machine.

npm install -g @vue/cli

Vue CLI helps us to create and manage Vue projects from the command line.

To check if Vue CLI has been installed, run the following command on your terminal:

vue --version

We will Now use the Vue CLI to build a simple application. To do that open up your terminal and type the following:

vue create cs-ecommerce

After installation, move into the folder using the cd cs-eCommerce.

Installing required packages

Vuex – Vuex is a central store for Vue.js applications. Data stored in the Vuex store can be accessed from any component in the application. To use Vuex in our project, we need to install it in our project. After we have it installed, we can call it from any part of our project.

npm install vuex --save

Vue Router – It is the official routing package for Vue.js. Vue router helps us to navigate the pages of our application. Each page has a specific path or URL or route that we register in our project’s routes.

vue add router

Axios – Axios is an NPM package for making HTTP requests in our node apps.
With Axios, our application can communicate with other web applications. We can send data and retrieve data from other web software through the Rest API.

There are other methods to communicate with web APIs, but we will install and use Axios for their ease and practicality in our project.

npm install axios

Creating the initial files.

Having Vuex already installed, we need to create a folder called store in our project’s root path.

In this directory, we will create two modules, one for the user and another for products.
We must also create an index.js file where we will import our store modules.

Inside the account and product folders, we need to create five files.

  1. state.js to store data or states
  2. getters.js to retrieve data,
  3. actions.js to create our functions,
  4. mutations.js to change states
  5. index.js to import all files from that module.
store/
├── account
│   ├── actions.js
│   ├── getters.js
│   ├── index.js
│   ├── mutations.js
│   └── state.js
├── index.js
└── product
    ├── actions.js
    ├── getters.js
    ├── index.js
    ├── mutations.js
    └── state.js

To see if it looks similar, you can use the tree command in the store path.

tree store

We can put states, getters, mutations, and actions in only JavaScript file. But for the organization, we will put each one in different files and inside a folder that we will call a module.

In step 1, you globally installed Vue CLI in your computer, created a Vue project, installed the required Npm packages Vuex, Axios, and Vue Router, and finally created the initial files required for Vuex.

Step 2 – Working with User module

In the index.js of the store path, place the code below to import the modules from the store modules. This is the heart of the Vuex.

//cs-ecommerce/src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import account from './account'
import product from './product'
Vue.use(Vuex)
export default function () {
  const Store = new Vuex.Store({
    modules: {
      account,
      product
    },
    // enable strict mode (adds overhead!)
    // for dev mode only
    strict: process.env.DEV
  })
  return Store
}

We will use state.js to store the data that can be accessed by any part of the application. For account, we only need to store user data In the user module state, we will create a function that returns an object with states of that module; in this case, we have only one state: the userData.

// cs-ecommerce/src/store/account/state.js
export default function () {
  return {
    userData: {},
  }
}

Getters returns the states; for getters of account module, we will create a function that returns the userData state.

//cs-ecommerce/src/store/account/getters.js
export function user (state) {
    return state.userData
}

It is only possible to change states through mutations. In the account module mutation, we will create a function that receives the userData state as a parameter and a value that will be assigned to it in the actions.js when some function commits it. The mutation function will assign the received value to the userData state.

//cs-ecommerce/src/store/account/mutations.js
export function setUserData(state, val) {
    state.userData = val
}

mutations.js is used to set data in the state

In action.js of the account module, we will access a dummy API with Axios to fetch a user and then store it in our state userData committing the mutations setUserData

//cs-ecommerce/src/store/account/actions.js
import router from '../../router'
import Axios from 'axios';
export function login({ commit }) {
    let url = 'https://randomuser.me/api/';
    Axios.get(url).then(function (response) {
        let userData = {
            displayName: response.data.results[0].name.first,
            email: response.data.results[0].email,
            photoURL: response.data.results[0].picture.thumbnail,
            uid: response.data.results[0].login.uuid
        }
        commit("setUserData", userData)
        router.push('/')
    })
        .catch(function (error) {
            console.log(error)
        });
}

In the index.js we will import getters, mutations, actions, and state.

//cs-ecommerce/src/store/account/index.js
import state from './state'
import * as getters from './getters'
import * as mutations from './mutations'
import * as actions from './actions'
export default {
  namespaced: true,
  getters,
  mutations,
  actions,
  state
}

In step 2, you created the user module to separate user states from the other application states.

Step 3 – Working with product module

In the product module, we need products state, product state for details of a product, and cart state to store the cart products.

  • products state – will store product list
  • product state – will store a specific product
  • cart state – will store product list in cart
//cs-ecommerce/src/store/product/state.js
export default function () {
  return {
    products: [],
    product: {},
    cart: []
  }
}

In the getters.js of the product module, we will create three functions:

  • products function – Returns the state that store the product list
  • product – Returns the state that store a specific product when the user wants to see the product details
  • cart – Returns the state that stores the products in the cart

//cs-ecommerce/src/store/product/getters.js
export function products (state) {
    return state.products
}
export function product (state) {
    return state.product
}
export function cart (state) {
    return state.cart
}

In the mutations.js of product module, we will create four functions.

  • setProducts – Assign product list to state products
  • setProduct – Assign an object with a specific product to the product state
  • setCart – Assigns a list of added products in the cart to cart state
//cs-ecommerce/src/store/product/mutations.js
export function setProducts(state, val) {
    state.products = val
}
export function setProduct(state, val) {
    state.product = val
}
export function setLoad(state, val) {
    state.uploadingData = val
}
export function setCart(state, val) {
    state.cart = val
}

Inside actions.js we will create a function to retrieve all products with Axios, a function to retrieve details of a product, a function to add the product to the cart and a function to remove the product from the cart

For this tutorial, we will use a dummy API generated by https://jsonplaceholder.typicode.com/
For this project, we created a JSON server with https://my-json-server.typicode.com/Nelzio/ecommerce-fake-json/products
Basically, on this JSON server, we put a JSON product list.

First, we need to import Axios to fetch data

//cs-ecommerce/src/store/product/actions.js
import axios from "axios"

Action to get products list


    export function getProducts({ commit }) {
        let url = "https://my-json-server.typicode.com/Nelzio/ecommerce-fake-json/products";
        axios.get(url).then((response) => {
            commit("setProducts", response.data);
        }).catch(error => {
            console.log(error);
        });
    }

The action to get products is effortless.
We have an endpoint or URL to get the data from the server, and then with the Axios, we do the get at that endpoint.

Action to get product details

//cs-ecommerce/src/store/product/actions.js
export function productDetails({ commit }, id) {
    let url = "https://my-json-server.typicode.com/Nelzio/ecommerce-fake-json/products";
    axios.get(url, { params: { id: id } }).then((response) => {
        commit("setProduct", response.data[0]);
    }).catch(function (error) {
        console.log(error);
    });
}

For details of a particular product, the concept does not change from the previous one. The difference is that in Axios, we pass a parameter to retrieve a product. The parameter is the id of the product that we want to see the details.

Action to add to cart.

//cs-ecommerce/src/store/product/actions.js
export function addCart({ commit, getters }, payload) {
    let cart = getters.cart
    cart.push(payload)
    commit("setCart", cart)
}

Our action will receive as a parameter an object of product and add it to the cart array.

let cart = getters.cart

It Catches what is in the cart and put it in a temporary variable

cart.push(payload)

It Pushes the product object to the temporary variable.

commit("setCart", cart)

Adds cart array to cart state.

//store/product/actions.js
export function removeCart({ commit, getters }, id) {
    let cart = []
    if (id) {
        for (let index = 0; index < getters.cart.length; index++) {
            const element = getters.cart[index];
            if (element.id !== id) {
                cart.push(element)
            }
        }
    }
    commit("setCart", cart)
}

To remove a particular object from the cart, we will iterate what is on the cart array and add items that not have the same product id that we want to remove to a temporary variable and then add the cart by committing its mutation.

In step 3, you created a product module to separate its states from other states of our application. The product module deals only with product states. You also used the Rest API generated on https://jsonplaceholder.typicode.com/ to fetch the data via Axios.

Step 4 – Creating the necessary Components

After having everything ready in our store, we will work with the visual part, our components.

In our project, we will use the bootstrap; you can use another framework for styling.
To add bootstrap, we need to add bootstrap CSS CDN inside the head tags of the index.html file in the public folder.

//cs-ecommerce/public/index.html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

We can now use bootstrap classes in our project.
Now let’s create a parent component that we will call layout.

Layout component

In our project’s root path, we will create a folder called layout, and inside of this folder, we’ll create a file called Base.vue that will be the layout for all our pages.

//cs-ecommerce/src/Layout/Base.html
<template>
  <div>
    <div>
      <nav class="navbar navbar-expand-lg navbar-dark fixed-top">
        <router-link class="navbar-brand" to="/">CS-eCommerce</router-link>
        <div class="ml-auto">
          <div v-if="user.photoURL">
            <img
              :src="user.photoURL"
              class="img-thumbnail profile-image"
              alt
            />
            <router-link class="btn btn-primary my-2 my-sm-0" to="/cart">
              <img
                src="https://pngimg.com/uploads/shopping_cart/shopping_cart_PNG38.png"
                width="50"
                alt
              />
              <span class="badge badge-danger badge-pill">{{ cart.length }}</span>
            </router-link>
          </div>
          <router-link v-else class="btn btn-primary my-2 my-sm-0" to="/login">Login</router-link>
        </div>
      </nav>
    </div>
    <div class="page-container">
      <router-view />
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
  name: "Base",
  computed: {
    ...mapGetters("account", ["user"]),
    ...mapGetters("product", ["cart"])
  }
};
</script>

<style>
</style>

Basically, in our layout, we have a navigation bar represented by the <nav> </nav> tags and a main container in the div with the page-container class where the router-view will inject all pages.

To add user and cart information, we will get the data from vuex with mapGetters, which will return us user and cart data that are in the states created previously.

Information about the user and cart can only be shown if the user is authenticated.

//cs-ecommerce/src/Layout/Base.html

<div v-if="user.photoURL">
  <img
    :src="user.photoURL"
    class="img-thumbnail profile-image"
    alt
  />
  <router-link class="btn btn-primary my-2 my-sm-0" to="/cart">
    <img
      src="https://pngimg.com/uploads/shopping_cart/shopping_cart_PNG38.png"
      width="50"
      alt
    />
    <span class="badge badge-danger badge-pill">{{ cart.length }}</span>
  </router-link>
</div>

For the user, we will show only his profile picture, and for cart, we only need to count how many items have been added, seeing the length of this array.

We will now create a folder called Home which will contain all products component.

Inside of Home folder, we’ll create the card component of the products ProductCard.vue

//cs-ecommerce/src/views/home/ProductCard.vue
<template>
  <div class="card mb-4 shadow-sm">
    <img :src="product.imageUrl" class="card-img-top product-image" />
    <div class="card-body">
      <h5 class="card-title text-left">{{ product.name }}</h5>
      <div class="row">
        <router-link
          type="button"
          class="btn btn-primary btn-lg"
          :to="'/details/' + product.id"
        >Details</router-link>
      </div>
    </div>
  </div>
</template>
<script>
export default {
    name: "ProductCard",
    props: ["product"]
};
</script>
<style>
.card .product-image {
  height: 300px;
}
</style>

After creating the product card, we will import it into the Product view and then place it within the product iteration. to do so Create a new file called Products.vue inside the Home folder.

//cs-ecommerce/src/views/home/Products.vue
<template>
  <div style="padding: 25px;">
    <div class="container">
      <div class="row">
        <div class="col-md-4" v-for="product in products" :key="product.id">
          <ProductCard :product="product" />
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { mapActions, mapGetters } from "vuex";
import ProductCard from "../../components/ProductCard";
export default {
  computed: {
    ...mapGetters("product", ["products"]),
  },
  components: { ProductCard },
  methods: {
    ...mapActions("product", ["getProducts", "addCart", "removeCart"]),
  },
  mounted() {
    this.getProducts();
  }
};
</script>
<style>
</style>

Action method to retrieve products

The code below is an excerpt from the actions.js of the products module that we made above.

The data comes from an API, and we will store it in a state by committing the mutation of that state. In that case, it is a product state.

//cs-ecommerce/src/store/product/actions.js
export function getProducts({ commit }) {
    let url = "https://my-json-server.typicode.com/Nelzio/ecommerce-fake-json/products";
    axios.get(url).then((response) => {
        commit("setProducts", response.data);
    }).catch(error => {
        console.log(error);
    });
}

To list the products on the Products page, we take the data in the products state, iterate that data, and place each item on a card.

Add to cart component

First, let’s create a folder called details & the component to add a product to the cart.
We will set the product, and the quantity to a state called cart.

//cs-ecommerce/src/components/details/AddToCart.html
<template>
  <div class="row">
    <div class="col-3">
      <label class="sr-only" for="inlineFormInputName2">Quantity</label>
      <input type="number" v-model="quantity" class="form-control mb-2 mr-sm-2" />
    </div>
    <button
      v-if="!isInCardProp"
      @click.stop="addCart({product, quantity})"
      type="button"
      class="btn btn-primary btn-lg btn-block col-9"
    >ADD TO CART</button>
    <button
      v-else
      @click.stop="removeCart(product.id)"
      type="button"
      class="btn btn-primary btn-lg btn-block col-9"
    >REMOVE FROM CART</button>
  </div>
</template>
<script>
import { mapActions, mapState } from "vuex";
export default {
  props: ["product"],
  data() {
    return {
      isInCardProp: false,
      quantity: 1,
    };
  },
  computed: {
    ...mapState("product", ["cart"]),
  },
  methods: {
    ...mapActions("product", ["addCart", "removeCart"]),
    isInCart(id) {
      for (let index = 0; index < this.cart.length; index++) {
        const element = this.cart[index];
        if (element.id === id) {
          return true;
        }
      }
      return false;
    },
  },
  watch: {
    product(val) {
      this.isInCardProp = this.isInCart(val.id);
    },
    cart() {
      this.isInCardProp = this.isInCart(this.product.id);
    },
    quantity(val) {
      if (val <= 0) {
        this.quantity = 1;
      }
    },
  },
};
</script>
<style>
</style>

To check if the product has been added to the cart, we have a method to check if this item is in the array.
This method is invoked when the product state or state cart has some change. So they are within watch block of those states.

To add a product to the cart, we take its information and quantity to add it to a single object and then store it in a state.

//cs-ecommerce/src/store/product/actions.js
export function addCart({ commit, getters }, payload) {
    let cart = getters.cart
    let data = payload.product
    data["quantity"] = payload.quantity
    cart.push(data)
    commit("setCart", cart)
}

To remove a product from the cart, we need to iterate the array in the products state and add each item to a temporary array if it is not the product to be removed and add that temporary array to the cart state.

//cs-ecommerce/src/store/product/actions.js
export function removeCart({ commit, getters }, id) {
    let cart = []
    if (id) {
        for (let index = 0; index < getters.cart.length; index++) {
            const element = getters.cart[index];
            if (element.id !== id) {
                cart.push(element)
            }
        }
    }
    commit("setCart", cart)
}

In the details view, we will show more details of the product and import the component to add the product details to the cart. The component to add a product to the cart must be shown only if the user is authenticated. also, the directive v-if is used to conditionally render a block.

//cs-ecommerce/src/views/home/Details.vue
<template>
  <div class="container-fluid">
    <div class="row d-flex justify-content-center">
      <div class="col-6">
        <div class="card text-left shadow-md">
          <img class="card-img-top" :src="product.imageUrl" alt />
        </div>
      </div>
      <div class="col-6 text-left text-justify">
        <div class="display-3">{{ product.name }}</div>
        <p class="lead text-justify">{{ product.content }}</p>
        <div>
          <p class="h3">Price</p>
          <p class="h2">${{ product.price }}</p>
        </div>
        <AddToCart :product="product" v-if="user.uid" />
      </div>
    </div>
  </div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import AddToCart from "../../components/details/AddToCart"
export default {
  data () {
    return {
      isInCardProp: false,
    }
  },
  computed: {
    ...mapGetters("account", ["user"]),
    ...mapGetters("product", ["product"])
  },
  components: { AddToCart },
  methods: {
    ...mapActions("product", ["productDetails"]),
  },
  mounted() {
    this.productDetails(this.$route.params.idProduct);
  }
};
</script>
<style>
.container-fluid {
  padding: 30px;
}
.image-product {
  width: 100%;
}
.card * {
  max-height: 85vh;
}
</style>

The component to add a product to the cart must be shown only if the user is authenticated.

On the cart page, we will list the products added to the cart and details such as the image, name, price, and quantity of product.
We will also calculate the total price of each product and the total to be paid. inside the home folder create a file called Cart.vue and add the following code

//cs-ecommerce/src/views/home/Cart.vue
<template>
  <div class="container" style="padding: 30px">
    <div class="row d-flex justify-content-center">
      <div class="list-group col-8">
        <a
          v-for="item in cart"
          :key="item.id"
          href="#"
          class="list-group-item list-group-item-action d-flex justify-content-between align-items-center"
        >
          <img :src="item.imageUrl" alt height="60" width="60" />
          <p class="h4">{{ item.name }}</p>
          <div class="row">
            <div class="mr-2">
              <p>Unique Price</p>
              <p>${{ item.price }}</p>
            </div>
            <div class="mr-2">
              <p>Total Price</p>
              <p>${{ item.price * item.quantity }}</p>
            </div>
            <div>
              <p>Quantity</p>
              <p>{{ item.quantity }}</p>
            </div>
          </div>
        </a>
        <div
          class="list-group-item list-group-item-action d-flex justify-content-between align-items-center"
        >
          <p class="h4">Total</p>
          <div>
            <p>Total Price</p>
            <p>${{ totalPrice }}</p>
          </div>
        </div>
        <button
          @click="checkout()"
          type="button"
          class="btn btn-primary btn-lg btn-block mt-4"
        >Checkout</button>
      </div>
    </div>
  </div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
  name: "Cart",
  data() {
    return {
      totalPrice: 0,
    };
  },
  computed: {
    ...mapGetters("product", ["cart"]),
    ...mapGetters("account", ["user"]),
  },
  methods: {
    ...mapActions("product", ["removeCart"]),
    calcPrice() {
      this.cart.forEach((element) => {
        this.totalPrice += element.price * element.quantity;
      });
    },
    checkout() {
      const vm = this;
      setTimeout(() => {
        vm.removeCart();
        alert("Purchase successful!");
        vm.$router.push("/");
      }, 2000);
    },
  },
  mounted() {
    this.calcPrice();
  },
};
</script>
<style>
</style>

We’ll create a simple authentication form, but we will not retrieve data. For login, we have a form with email and password fields that will not be used. And we have a button that will call the login function in the action of the account module previously created. To do so create a folder called account and add the Login.vue file inside the account folder.

//cs-ecommerce/src/views/account/Login.vue
<template>
  <div>
    <div class="container" style="padding-top: 10%">
      <div class="row d-flex justify-content-center">
        <div class="col-5 text-left login-form-container">
          <div class="d-flex justify-content-center">
            <img src="https://cdn0.iconfinder.com/data/icons/set-ui-app-android/32/8-512.png" width="150" alt="">
          </div>
          <div>
            <div class="form-group">
              <label for="exampleInputEmail1">Email address</label>
              <input
                type="email"
                class="form-control"
                id="exampleInputEmail1"
                aria-describedby="emailHelp"
              />
              <small
                id="emailHelp"
                class="form-text text-muted"
              >We'll never share your email with anyone else.</small>
            </div>
            <div class="form-group">
              <label for="exampleInputPassword1">Password</label>
              <input type="password" class="form-control" id="exampleInputPassword1" />
            </div>
            <div class="form-group form-check">
              <input type="checkbox" class="form-check-input" id="exampleCheck1" />
              <label class="form-check-label" for="exampleCheck1">Check me out</label>
            </div>
            <button @click="login()" type="submit" class="btn btn-primary btn-block">Login</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { mapActions } from "vuex";
export default {
  name: "Login",
  methods: {
    ...mapActions("account", ["login"]),
  },
};
</script>

<style>
</style>

For login, we have to get data from an API and save it in the user state.
In our application, we will not log in. We will take a user from randomuser.me and store it in our user state. If the object in the user state is empty, we will assume that the user has not been authenticated.

//cs-ecommerce/src/store/account/actions.js
export function login({ commit }) {
    let url = 'https://randomuser.me/api/';
    Axios.get(url).then(function (response) {
        let userData = {
            displayName: response.data.results[0].name.first,
            email: response.data.results[0].email,
            photoURL: response.data.results[0].picture.thumbnail,
            uid: response.data.results[0].login.uuid
        }
        commit("setUserData", userData)
        router.push('/')
    })
        .catch(function (error) {
            console.log(error)
        });
}

In step 4, first, you added the bootstrap in your project, then you created the necessary vue components required in your app, and finally, you used the randomuser.me API to store the user from the API to your User state.

Step 5 – Applying some aesthetics to the UI

Now let’s add some style to our app. We will do this in our base layout. In fact, styling is made within the <style> </style> tags.

//cs-ecommerce/src/layout/Base.vue
<style>
nav {
  background-color: teal;
}
.navbar-brand {
  font-weight: bold;
  font-size: 25px;
  color: #ffffff !important;
}
.profile-image {
  width: 50px;
  border-radius: 100% !important;
}
.page-container {
  padding-top: 81px;
}
.btn {
  border-radius: 0%;
  font-weight: bold;
  background: teal;
  border: teal;
}
.btn:hover {
  background: #00b4b4;
}
input {
  border-radius: 0%;
}
.btn:focus {
  background: teal;
}
</style>

In the CSS snippet above we have taken the main classes and main tags and made some necessary modifications. we have also some CSS selectors including .profile-image.page-container.navbar-brand.btn.btn:hover and .btn:focus.

  • .profile-image sets profile image size in our app
  • .page-container just defines top padding in our app.
  • .input makes buttons with square borders
  • .btn, we changed the color.
  • .btn:hover We set the hover color, which means when a user will hover the mouse on the button, the color will change to the color we have set.

Let’s also add some styling to our login page.

//cs-ecommerce/src/views/account/login.vue
<style>
.form-control {
  border-radius: 0%;
  height: 50px;
}
.login-form-container {
  padding: 20px;
  box-shadow: 0px 2px 5px 2px #888888;
}
.btn {
  border-radius: 0%;
  font-weight: bold;
  background: teal;
  border: teal;
}
.btn:hover {
  background: #00b4b4;
}
.btn:focus {
  background: teal;
}
</style>

For the login component, we added a shadow border to the div of the form and changed the color of the button, and made the button inputs square. the .login-form-container CSS selector sets the padding of that form inputs with the box shadow around the inputs.

In step 5, you added the styling to your app and made your app look cleaner and nicer.

Run the application

We have finished building our eCommerce application. Now it’s time to run our newly build application.

npm run serve

This starts a development server that allows you to view your app on http://localhost:8080.

Conclusion

Now we can build eCommerce using Vue and Vuex consuming data from an API. Although the data comes from a dummy API, the logic is the same, but in every API, it’s essential to read the documentation to learn how to fetch data.

I hope you learned a few things about Vue. Every article can be made better, so please leave your suggestions and contributions in the comments below. If you have questions about any of the steps, please do also ask in the comments section below.

You can Checkout Source Code on Github


Share on social media

//