Let’s Add Products for our eCommerce App with Vue.js
Published: 2021-01-14 19:53:09

We are building a complete E-commerce application from scratch. Today we are going to add the Products feature.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4sfog7jzvwveb0v0rau5.png)

## Introduction

As part of building an E-Commerce application, previously we built the backend for UserProfiles and created android UI for the same.

{% medium https://medium.com/technology-hits/lets-develop-an-ecommerce-application-from-scratch-using-java-and-spring-6dfac6ce5a9f %}

{% medium https://medium.com/technology-hits/android-ui-for-e-commerce-user-profile-backend-4053ab122a13 %}

The most important part of an online shop is products. We are going to create product backend APIs and consume those APIs in our web front-end built using the shiny Vue.js framework.

## Demo

[Webtutsplus E-commerce App](http://remotedevs.org:8000/)
{% youtube oh8mse1eD3U %}

## Database Design

This is a sample JSON of a product, we will link it to a category and add other fields in later tutorials.
{% gist https://gist.github.com/nilmadhab1995/461135d4801d694cdf94d61042130219.js %}

{% gist https://gist.github.com/nilmadhab1995/3f869c0e9cafaf66211eeb67a2e6d71e.js %}
<figcaption>products.sql</figcaption>

Each product has a unique ID, name, image URL, price, description. We can model it in Springboot as

{% gist https://gist.github.com/nilmadhab1995/dd5e94b8f9ae535dfaa7c4a519cb9e35.js %}

## API Design

In the real-world, we need to see the products, create new products, and update the products. So we will create 3 APIs. Later we will create many other real-world features like deleting, stocks, linking to categories, and adding tags. After this, we will create the UI.

{% gist https://gist.github.com/nilmadhab1995/bb6a374bd369c7ecb30df807d1e34efd.js %}

<figcaption>Product controller to create, add and update products</figcaption>



![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j0msr8zwd1z2dot51w5o.png)
<figcaption>Swagger listing of APIs</figcaption>

You can find the backend code in this [branch](https://bitbucket.org/ecommerce-webtutsplus/ecommerce/src/596dd222404adcdd5541ddd04e48f9b75dfa3205/?at=nmadhab%2Fproducts-v1-first-tutorial)

## Vue.js introduction

We will use Vue.js 3 to design the front end for displaying products of our E-commerce app.

Vue is a JavaScript framework that is used to build user interfaces. The official page of Vue describes it as a “progressive framework” which is “incrementally adoptable”. Both of these terms roughly relate to the same meaning. Vue can be used in two ways. We can either create a full Vue website, commonly known as a Single-page application or we can create stand-alone widgets (also known as components) which we can then use in our HTML as an addition. This way, the adoption of Vue in our application is totally in our hands. In this tutorial, we will be creating a Vue component to display products of our E-Commerce App.
## Vue.js Requirements

As we are just creating a single widget for displaying the product and its details, we can make use of the Vue CDN from its installation page and carry on. Using Vue CDN is a beginner-friendly way to start our journey. For bigger projects, a different setup using Vue CLI is recommended. As a code editor, I will be using VS Code, but you can use any editor of your choice. First, we will create the following three files.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vwa59mux0ut5urlxxpy0.png)

## Let’s get started

First, let us set up the boilerplate for index.html. Our very first requirement is Vue CDN. Apart from this, I am also including Bootstrap 4 CDN and some Google fonts which I will be using. And for my custom styles, I am also including the link to my external CSS file. Also, include the script tag to link our JavaScript file app.js in the body tag. After all these things are done, our index.html will look like this:

{% gist https://gist.github.com/ChitreshApte/a396749c14ca0b17541e44806ef2378a.js %}

We will revisit this file once we are done with our app.js file.

You can find the complete code [here](https://bitbucket.org/ecommerce-webtutsplus/ecommerce-ui/src/68a63aa70194f9064e8be0115f86e95293fe1a05/?at=chitresh%2Fvue.js-product-edit)


## Creating a Vue Component

Now it's time for our app.js file, where we will be writing the logic for creating our Vue Component. To create a component, Vue provides us with a method createApp(). This method takes as a parameter a component instance. This instance is made up of various component options and Lifecycle hooks that add user-defined behaviour to the component.
**Component Options**

We will be using two of the component options — data and methods.

* The data option lists all the data fields which are exposed by our component instance.
* The methods option lists all the functions which we might need to use. For example, here we can define a function to execute whenever some button in our component template is clicked.

**Lifecycle Hooks**

Apart from these component options, our component instance also consists of Lifecycle hooks. Lifecycle hooks are the functions that our component automatically runs at different stages of its initialization. These stages include when a component is created, added to the DOM, updated, or destroyed. We will be using the lifecycle hook, mounted. This function is called when our component is added to the DOM. In this function, we can make HTTP requests to fetch data for our component.
## Our Component

So in our case, the data option consists of six fields. A product array to store our products, showAddForm(a boolean value) to decide whether to display form for adding a new product and four-string data fields which we will use to get input from the user for product edit functionality.
```
data() {
    return {
        products : null,
        showAddForm : false,
        tempName : "",
        tempDescription : "",
        tempPrice : "",
        tempImageURL : "" 
    }
}
```

In methods option, we have five methods,**resetInputFields, addProductButtonPressed, addProduct, editButtonPressed and editProduct.**

* **resetInputFields -** it sets the values of all data fields bound to the input form to an empty string.
* **addProductButtonPressed -** it toggles the display of form used for adding a new product. It gets executed whenever the user clicks the “Add a New Product” button.
* **addProduct -** it creates a new product as per the user input and makes a POST request to backend API to add this product. It gets executed when the user submits the form for adding a new product.
* **editButtonPressed -** it toggles the form for editing a product based on the product’s showEditForm property and sets the values of input fields as per the invoking product details. It gets executed when the user clicks the “Edit” button. For distinguishing the product, this method takes the index of the product as a method argument.
* **editProduct-** it creates a new product as per the user input and makes a POST request to backend API to update the product details. This method also takes the index of the product as a method argument. It gets executed when the user submits the form for editing a product. The backend API makes use of the product’s unique id to update its details.

In mounted life cycle hook, we fetch all the products from the E-Commerce API and store them in the products array. In addition to this, we also add a property showEditForm to all products and set it to false.
```
mounted : async function mounted(){
    const response  = await fetch(urlGetProduct);
    this.products = await response.json();
    for(product of this.products) {
        product.showEditForm = false;
    }
}
```

Now that our component is created we have to add this component to our DOM. For this, we make use of the mount method.
```
app.mount("#app");
```

This statement mounts our component to the HTML element with id “app”. Now our Vue component controls everything inside this element. We can make this HTML element to render dynamic data, add interactivity and handle events occurring inside it. This completes the creation of our Vue component in app.js.

{% gist https://gist.github.com/ChitreshApte/9ece8ccb2ac2988354d8ca38ebd4bed2.js %}

## Designing the Component’s Template

We are now back to our index.html file.

We have created an h1 tag for displaying the heading at the top of the web page. Then we have to create a div element with id as “app”. This will be the playground of our Vue component. All the data fields declared in our component’s data option are accessible here. First, we will design a form for adding a new product. Then a section to display product details. Finally, a form for editing products. This will be very similar to the first form.

For achieving all this, Vue gives us the power of directives.
**Vue Directives**

Directives are like instructions to Vue to do something. Vue provides us with many directives in our armoury. These directives can be used for listening to events and conditional rendering of HTML elements to the DOM.
## Add Form

Let’s start with the add form. Here we will use the directives **“v-on”** and “v-show”. The **“v-on”** directive is used for listening to DOM events. This includes events like clicking, hovering, scrolling and many more. We will use this directive to listen to click events on the “Add a new product” button. On this click event, we can either perform some JavaScript logic or we can call some method of our component declared earlier. While calling the method, we can also pass arguments.
```
<button v-on:click=”addProductButtonPressed”> Add Product </button>
```
Vue also provides shortcuts for some directives. For example, **“v-on”** can be replaced with @ symbol.
```
<button @click=”addProductButtonPressed”> Add Product </button>
```
We will use the “v-show” directive to show the form for adding products. The “v-show” directive can be used to toggle the display of some HTML element based on some boolean condition. In the form, we will make use of the boolean variable showAddForm to decide whether to display the form or not.

Now in designing the form, we make use of the “v-model” directive. We can use this directive in the input fields of the form. This creates a two-way binding between the input fields and the data fields of our component. This way we can easily read the input values and even reset them when required.
```
<input type="text" placeholder="Enter name" v-model="tempName">
```
At the bottom of the form will be a submit button. Here also we will make use of the “v-on” directive to listen to the click event.
Product Details

In a div element with class “products-box”, we will use the directive “v-for” for looping through the products array. In the loop, along with the individual product, we will also keep a count of the index.

Now the interesting part is, inside this div, all the HTML elements will be rendered one after the other for all the individual products. And for different products, we will be displaying dynamic content based on the product details.

We can use “v-bind” for binding the attributes of HTML element with dynamic content.
```
<img v-bind:src=”product.imageURL” alt=”product-image”>
```
Along with “v-for” directive we also have access to “v-if” and “v-else” directive which we can use in an if-else situation. But, it is beneficial to use **“v-show”**, instead of “v-if” anywhere possible because **“v-show”** only displays or hides the content. In case the condition is false, it does not remove any part from the DOM, it just hides it. For displaying dynamic text content, we have to wrap data fields inside double braces.
```
<h2 class="product_name">{{product.name}}</h2>
```
** Edit Product

Finally, we will design the form for edit product functionality. The layout of this form will be similar to the earlier form. We will be using the same directives **“v-show”**, **“v-on”** and **“v-model”**. The only difference will be the logic for handling the submission of the form.

So after designing the component template, our index.html will look something like this:

{% gist https://gist.github.com/ChitreshApte/441a353309e45fe2c28567907f0eec7f.js %}

In this HTML file, the div element with class “product-item” encapsulates displaying the product details and its edit form. It is this div element, which is rendered for all the products.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nvr0okxvlj5en22pp7bh.png)

CSS

Let’s also add some custom CSS :
{% gist https://gist.github.com/ChitreshApte/2596c0ada716ac1254a5e24c24b6da81.js %}

So now we have a front-end to display all the products and their details. We have also got the functionality to add new products and edit the existing ones.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v832dnkpywb8jcbgum6h.png)

## Why use a framework?

Front-end frameworks have made the lives of developers a lot easier. The biggest advantage of using a framework over traditional JavaScript is the link between our data and its presentation. Using frameworks, developers do not need to worry about writing the code for updating DOM when some variables change. Frameworks achieve this very easily using two-way binding. Along with easing our work, some frameworks also provide additional features like routing, which can be used to create Single Page Applications.
## But why Vue.js?

Vue.js is getting backed by a lot of developers. The Vue.js community is rapidly growing. The recent updates to Vue have made it a lot more robust. Many prefer Vue.js over other frameworks because of its ease-of-use, its performance, and its compact size. The official documentation of Vue is a great resource to get a deep dive into the framework. Many also consider Vue as a combination of all good parts of React and Angular. Hence, Vue.js is worth giving a try.
Follow the next tutorial in the series, where we will create categories and link products with categories.

{% medium https://medium.com/javascript-in-plain-english/lets-link-product-with-category-for-our-ecommerce-app-28100657a848 %}

## Resources

{% medium https://medium.com/webtutsplus/creating-a-simple-vue-js-website-for-our-backend-1d1ef8839c27 %}

* [Bootstrap 4 CDN](https://getbootstrap.com/docs/4.0/getting-started/introduction/)
* [Frontend Code](https://bitbucket.org/ecommerce-webtutsplus/ecommerce-ui/src/68a63aa70194f9064e8be0115f86e95293fe1a05/?at=chitresh%2Fvue.js-product-edit)
* [Backend code](https://bitbucket.org/ecommerce-webtutsplus/ecommerce/src/596dd222404adcdd5541ddd04e48f9b75dfa3205/?at=nmadhab%2Fproducts-v1-first-tutorial)
* [Vue.js 3](https://v3.vuejs.org/guide/introduction.html)
* [Swagger-UI for the API](http://remotedevs.org:8080/api/swagger-ui.html)
* [Google Fonts](https://fonts.google.com/)
* [Backend API Repository](https://bitbucket.org/ecommerce-webtutsplus/ecommerce/src/master/)

**Thank You for Reading!**