Vuejs Shopping Cart Application vue ecommerce

Vuejs Shopping Cart Application vue ecommerce

In this Post We Will Explain About is Vuejs Shopping Cart Application vue ecommerce With Example and Demo.

Welcome on infinityknow.com – Examples ,The best For Learn web development Tutorials,Demo with Example! Hi Dear Friends here u can know to Shopping Cart Application Built with Vuejs

In this post we will show you Best way to implement Shopping Cart Application using Vuejs, hear for How to Create Shopping Cart with Vuejs with Download .we will give you demo,Source Code and examples for implement Step By Step Good Luck!.

Vuejs Shopping Cart Application

index.html

<div class="main-wrapper">
  <div class="header"><h1>Vue Shopping Cart - infinityknow.com</h1></div>
  <div id="vue">
    <shopcrat :shopcrat="shopCrat" :shopcrat-sub-total="shopcartSubtotal" :billtax="billtax" :shopcrat-total="shptotal" :checkout-bool="checkCartData"></shopcrat>
    <items :shopcrat="shopCrat" :shopcrat-sub-total="shopcartSubtotal" :billtax="billtax" :shopcrat-total="shptotal" :items-data="itemsData"></items>
    <checkout-area v-if="checkCartData" :shopcrat="shopCrat" :billtax="billtax" :shopcrat-sub-total="shopcartSubtotal" :shopcrat-total="shptotal" :items-data="itemsData" :total-with-billtax="totalWithTax"></checkout-area>
  </div>
</div>

index.js

Vue.component('items', {
  
  ready: function () {
    var myself = this;
    document.addEventListener("keydown", function(e) {
      if (myself.newModal && e.keyCode == 37) {
        myself.changeItemsInModal("prev");
      } else if (myself.newModal && e.keyCode == 39) {
        myself.changeItemsInModal("next");
      } else if (myself.newModal && e.keyCode == 27) {
        myself.dataHidePopup();
      }
    });
  },

  template: "<h1>Items</h1>" + 
  "<div class='items'>" +
  "<div v-for='item in itemsData' track-by='$index' class='item {{ item.item | lowercase }}'>" + 
  "<div class='image' @click='viewItem(item)' v-bind:style='{ backgroundImage: \"url(\" + item.image + \")\" }' style='background-size: cover; background-position: center;'></div>" +
  "<div class='name'>{{ item.item }}</div>" +
  "<div class='itemdesc'>{{ item.itemdesc }}</div>" +
  "<div class='productprice'>{{ item.productprice | currency }}</div>" +
  "<button @click='addToCart(item)'>Add to Cart</button><br><br></div>" +
  "</div>" +
  "<div class='modalWrapper' v-show='newModal'>" +
  "<div class='prevProduct' @click='changeItemsInModal(\"prev\")'><i class='fa fa-angle-left'></i></div>" +
  "<div class='nextProduct' @click='changeItemsInModal(\"next\")'><i class='fa fa-angle-right'></i></div>" +
  "<div class='overlay' @click='dataHidePopup()'></div>" + 
  "<div class='modal'>" + 
  "<i class='close fa fa-times' @click='dataHidePopup()'></i>" + 
  "<div class='imageWrapper'><div class='image' v-bind:style='{ backgroundImage: \"url(\" + modalData.image + \")\" }' style='background-size: cover; background-position: center;' v-on:mouseover='imageMouseOver($getevent)' v-on:mousemove='imageMouseMove($getevent)' v-on:mouseout='imageMouseOut($getevent)'></div></div>" +
  "<div class='additionalImages' v-if='modalData.images'>" + 
  "<div v-for='image in modalData.images' class='additionalImage' v-bind:style='{ backgroundImage: \"url(\" + image.image + \")\" }' style='background-size: cover; background-position: center;' @click='changeImage(image.image)'></div>" +
  "</div>" +
  "<div class='name'>{{ modalData.item }}</div>" +
  "<div class='itemdesc'>{{ modalData.itemdesc }}</div>" +
  "<div class='details'>{{ modalData.details }}</div>" +
  "<h3 class='productprice'>{{ modalData.productprice | currency }}</h3>" +
  "<label for='datamodalAmt'>QTY</label>" +
  "<input id='datamodalAmt' value='{{ datamodalAmt }}' v-model='datamodalAmt' class='amount' @keyup.enter='modalAddToCart(modalData), dataHidePopup()'/>" +
  "<button @click='modalAddToCart(modalData), dataHidePopup()'>Add to Cart</button>" +
  "</div></div>",

  props: ['itemsData', 'shopCrat', 'billtax', 'shopcartSubtotal', 'shptotal'],

  data: function() {
    return {
      newModal: false,
      modalData: {},
      datamodalAmt: 1,
      timeout: "",
      mousestop: ""
    }
  },

  methods: {
    addToCart: function(item) {
      var found = false;

      for (var i = 0; i < vue.shopCrat.length; i++) {

        if (vue.shopCrat[i].sku === item.sku) {
          var newProduct = vue.shopCrat[i];
          newProduct.qty = newProduct.qty + 1;
          vue.shopCrat.$set(i, newProduct);
          found = true;
          break;
        }
      }

      if(!found) {
        item.qty = 1;
        vue.shopCrat.push(item);
      }

      vue.shopcartSubtotal = vue.shopcartSubtotal + item.productprice;
      vue.shptotal = vue.shopcartSubtotal + (vue.billtax * vue.shopcartSubtotal);
      vue.checkCartData = true;
    },

    modalAddToCart: function(modalData) {
      var myself = this;

      for(var i = 0; i < myself.datamodalAmt; i++) {
        myself.addToCart(modalData);
      }

      myself.datamodalAmt = 1;
    },

    viewItem: function(item) {      
      var myself = this;
      myself.modalData = (JSON.parse(JSON.stringify(item)));
      myself.newModal = true;
    },

    changeItemsInModal: function(direction) {
      var myself = this,
          ItemsLength = vue.itemsData.length,
          currentProduct = myself.modalData.sku,
          newProductId,
          newProduct;

      if(direction === "next") {
        newProductId = currentProduct + 1;

        if(currentProduct >= ItemsLength) {
          newProductId = 1;
        }

      } else if(direction === "prev") {
        newProductId = currentProduct - 1;

        if(newProductId === 0) {
          newProductId = ItemsLength;
        }
      }

      for (var i = 0; i < ItemsLength; i++) {
        if (vue.itemsData[i].sku === newProductId) {
          myself.viewItem(vue.itemsData[i]);
        }
      }
    },

    dataHidePopup: function() {
      var myself = this;
      myself.modalData = {};
      myself.newModal = false;
    },

    changeImage: function(image) {
      var myself = this;
      myself.modalData.image = image;
    },

    imageMouseOver: function(getevent) {
      getevent.target.style.transform = "scale(2)";
    },

    imageMouseMove: function(getevent) {
      var myself = this;
      
      getevent.target.style.transform = "scale(2)";
      
      myself.timeout = setTimeout(function() {
        getevent.target.style.transformOrigin = ((getevent.pageX - getevent.target.getBoundingClientRect().left) / getevent.target.getBoundingClientRect().width) * 100 + '% ' + ((getevent.pageY - getevent.target.getBoundingClientRect().top - window.pageYOffset) / getevent.target.getBoundingClientRect().height) * 100 + "%";
      }, 50);
      
      myself.mouseStop = setTimeout(function() {
        getevent.target.style.transformOrigin = ((getevent.pageX - getevent.target.getBoundingClientRect().left) / getevent.target.getBoundingClientRect().width) * 100 + '% ' + ((getevent.pageY - getevent.target.getBoundingClientRect().top - window.pageYOffset) / getevent.target.getBoundingClientRect().height) * 100 + "%";
      }, 100);
    },

    imageMouseOut: function(getevent) {
      getevent.target.style.transform = "scale(1)";
    }
  }
});

Vue.component('shopCrat', {
  template: '<div class="shopCrat">' + 
  '<span class="shopCrat-size" @click="showCart = !showCart"> {{ shopCrat | totalcartsize }} </span><i class="fa fa-shopping-shopCrat" @click="showCart = !showCart"></i>' +
  '<div class="shopCrat-items" v-show="showCart">' +
  '<table class="cartTable">' +
  '<tbody>' +
  '<tr class="item" v-for="item in shopCrat">' +
  '<td class="align-left"><div class="cartImage" @click="deleteItems(item)" v-bind:style="{ backgroundImage: \'url(\' + item.image + \')\' }" style="background-size: cover; background-position: center;"><i class="close fa fa-times"></i></div></td>' +
  '<td class="align-center"><button @click="quantityChange(item, \'decriment\')"><i class="close fa fa-minus"></i></button></td>' +
  '<td class="align-center">{{ shopCrat[$index].qty }}</td>' +
  '<td class="align-center"><button @click="quantityChange(item, \'incriment\')"><i class="close fa fa-plus"></i></button></td>' +
  '<td class="align-center">{{ shopCrat[$index] | customPluralize }}</td>' +
  '<td>{{ item.productprice | currency }}</td>' +
  '</tbody>' +
  '<table>' +
  '</div>' +
  '<h4 class="shopcartSubtotal" v-show="showCart"> {{ shopcartSubtotal | currency }} </h4></div>' +
  '<button class="clearCart" v-show="checkCartData" @click="clearCart()"> Clear Cart </button>' +
  '<button class="checkoutCart" v-show="checkCartData" @click="propagateCheckout()"> Checkout </button>',

  props: ['checkCartData', 'shopCrat', 'totalcartsize', 'shopcartSubtotal', 'billtax', 'shptotal'],

  data: function() {
    return {
      showCart: false
    }
  },

  filters: {
    customPluralize: function(shopCrat) {      
      var newName;

      if(shopCrat.qty > 1) {
        if(shopCrat.item === "Peach") {
          newName = shopCrat.item + "es";
        } else if(shopCrat.item === "Puppy") {
          newName = shopCrat.item + "ies";
          newName = newName.replace("y", "");
        } else {
          newName = shopCrat.item + "s";
        }

        return newName;
      }

      return shopCrat.item;
    },

    totalcartsize: function(shopCrat) {
      var totalcartsize = 0;

      for (var i = 0; i < shopCrat.length; i++) {
        totalcartsize += shopCrat[i].qty;
      }

      return totalcartsize;
    }
  },

  methods: {
    deleteItems: function(item) {
      vue.shopCrat.$remove(item);
      vue.shopcartSubtotal = vue.shopcartSubtotal - (item.productprice * item.qty);
      vue.shptotal = vue.shopcartSubtotal + (vue.billtax * vue.shopcartSubtotal);

      if(vue.shopCrat.length <= 0) {
        vue.checkCartData = false;
      }
    },

    clearCart: function() {
      vue.shopCrat = [];
      vue.shopcartSubtotal = 0;
      vue.shptotal = 0;
      vue.checkCartData = false;
      this.showCart = false;
    },

    quantityChange: function(item, direction) {
      var qtyChange;

      for (var i = 0; i < vue.shopCrat.length; i++) {
        if (vue.shopCrat[i].sku === item.sku) {

          var newProduct = vue.shopCrat[i];

          if(direction === "incriment") {
            newProduct.qty = newProduct.qty + 1;
            vue.shopCrat.$set(i, newProduct);

          } else {
            newProduct.qty = newProduct.qty - 1;

            if(newProduct.qty == 0) {
              vue.shopCrat.$remove(newProduct);

            } else {
              vue.shopCrat.$set(i, newProduct);
            }
          }
        }
      }

      if(direction === "incriment") {
        vue.shopcartSubtotal = vue.shopcartSubtotal + item.productprice;

      } else {
        vue.shopcartSubtotal = vue.shopcartSubtotal - item.productprice;
      }

      vue.shptotal = vue.shopcartSubtotal + (vue.billtax * vue.shopcartSubtotal);

      if(vue.shopCrat.length <= 0) {
        vue.checkCartData = false;
      }
    },
    propagateCheckout: function() {
      vue.$dispatch("checkoutRequest");
    }
  }
});

Vue.component('checkout-area', {
  template: "<h1>Checkout Area</h1>" + 
  '<div class="checkout-area">' + 
  '<span> {{ shopCrat | totalcartsize }} </span><i class="fa fa-shopping-shopCrat"></i>' +
  '<table>' +
  '<thead>' +
  '<tr>' +
  '<th class="align-center">SKU</th>' +
  '<th>Name</th>' +
  '<th>Description</th>' +
  '<th class="align-right">Amount</th>' +
  '<th class="align-right">Price</th>' +
  '</tr>' +
  '</thead>' +
  '<tbody>' +
  '<tr v-for="item in shopCrat" track-by="$index">' +
  '<td class="align-center">{{ item.sku }}</td>' +
  '<td>{{ item.item }}</td>' +
  '<td>{{ item.itemdesc }}</td>' +
  '<td class="align-right">{{ shopCrat[$index].qty }}</td>' +
  '<td class="align-right">{{ item.productprice | currency }}</td>' +
  '</tr>' +
  //'<button @click="deleteItems(item)"> X </button></div>' +
  '<tr>' +
  '<td> </td>' +
  '<td> </td>' +
  '<td> </td>' +
  '<td> </td>' +
  '<td> </td>' +
  '</tr>' +
  '<tr>' +
  '<td></td>' +
  '<td></td>' +
  '<td></td>' +
  '<td class="align-right">Subtotal:</td>' +
  '<td class="align-right"><h4 v-if="shopcartSubtotal != 0"> {{ shopcartSubtotal | currency }} </h4></td>' +
  '</tr>' +
  '<tr>' +
  '<td></td>' +
  '<td></td>' +
  '<td></td>' +
  '<td class="align-right">Tax:</td>' +
  '<td class="align-right"><h4 v-if="shopcartSubtotal != 0"> {{ shptotal - shopcartSubtotal | currency }} </h4></td>' +
  '</tr>' +
  '<tr>' +
  '<td></td>' +
  '<td></td>' +
  '<td></td>' +
  '<td class="align-right vert-bottom">Total:</td>' +
  '<td class="align-right vert-bottom"><h2 v-if="shopcartSubtotal != 0"> {{ shptotal | currency }} </h2></td>' +
  '</tr>' +
  '</tbody>' +
  '</table>' +
  '<button v-show="shopcartSubtotal" @click="checkoutModal()">Checkout</button></div>' + 
  "<div class='modalWrapper' v-show='newModal'>" +
  "<div class='overlay' @click='dataHidePopup()'></div>" + 
  "<div class='modal checkout'>" + 
  "<i class='close fa fa-times' @click='dataHidePopup()'></i>" + 
  "<h1>Checkout</h1>" +
  "<div>We accept: <i class='fa fa-stripe'></i> <i class='fa fa-cc-visa'></i> <i class='fa fa-cc-mastercard'></i> <i class='fa fa-cc-amex'></i> <i class='fa fa-cc-discover'></i></div><br>" +
  "<h3> Subtotal: {{ shopcartSubtotal | currency }} </h3>" +
  "<h3> Tax: {{ shptotal - shopcartSubtotal | currency }} </h4>" +
  "<h1> Total: {{ shptotal | currency }} </h3>" +
  "<br><div>This is where our payment processor goes</div>" +
  "</div>",

  props: ['shopCrat', 'totalcartsize', 'shopcartSubtotal', 'billtax', 'shptotal'],

  data: function() {
    return {
      newModal: false
    }
  },

  filters: {
    customPluralize: function(shopCrat) {      
      var newName;

      if(shopCrat.qty > 1) {
        newName = shopCrat.item + "s";
        return newName;
      }

      return shopCrat.item;
    },

    totalcartsize: function(shopCrat) {
      var totalcartsize = 0;

      for (var i = 0; i < shopCrat.length; i++) {
        totalcartsize += shopCrat[i].qty;
      }

      return totalcartsize;
    }
  },

  methods: {
    deleteItems: function(item) {
      vue.shopCrat.$remove(item);
      vue.shopcartSubtotal = vue.shopcartSubtotal - (item.productprice * item.qty);
      vue.shptotal = vue.shopcartSubtotal + (vue.billtax * vue.shopcartSubtotal);

      if(vue.shopCrat.length <= 0) {
        vue.checkCartData = false;
      }
    },

    checkoutModal: function() {
      var myself = this;
      myself.newModal = true;

    },

    dataHidePopup: function() {
      var myself = this;
      myself.newModal = false;
    }
  },
  
  events: {
    "checkoutRequest": function() {
      var myself = this;
      myself.checkoutModal();
    }
  }
});


Vue.config.debug = false;
var vue = new Vue({
  el: "#vue",

  data: {
    itemsData: [
      {
        sku: 1,
        item: "laptop",
        image: "https://infinityknow.com/241793/chimpanzee.jpg",
        images: [
          { image: "https://infinityknow.com/241793/chimpanzee.jpg" },
          { image: "https://infinityknow.com/241793/gorilla.jpg" },
          { image: "https://infinityknow.com/241793/red-laptop.jpg" },
          { image: "https://infinityknow.com/241793/mandrill-laptop.jpg" }
        ],
        itemdesc: "This is a laptop",
        details: "This is where some detailes on laptop would go. This laptop done seent some shit.",
        productprice: 5.50
      },

      {
        sku: 2,
        item: "computers",
        image: "https://infinityknow.com/241793/computers.jpg",
        itemdesc: "This is a computers",
        details: "This is where some detailes on computers would go. Shout out computers for being adorable.",
        productprice: 10
      },

      {
        sku: 3,
        item: "DVD",
        image: "https://infinityknow.com/241793/DVD.jpg",
        itemdesc: "This is a DVD",
        details: "This is where some detailes on DVD would go. Damn nature, you DVD.",
        productprice: 15
      },

      {
        sku: 4,
        item: "pendrive",
        image: "https://infinityknow.com/241793/dog.jpg",
        itemdesc: "This is a pendrive",
        details: "This is where some detailes on pendrive would go. Shout out pendrive for being adorable.",
        productprice: 5
      },

      {
        sku: 5,
        item: "mouse",
        image: "https://infinityknow.com/241793/mouse.jpg",
        itemdesc: "This is an mouse",
        details: "This is where some detailes on mouse would go. Shout out mouse for being delicious.",
        productprice: 1
      },

      {
        sku: 6,
        item: "Orange",
        image: "https://infinityknow.com/241793/orange.jpg",
        itemdesc: "This is an orange",
        details: "This is where some detailes on oranges would go. Shout out oranges for being delicious.",
        productprice: 1.1
      },

      {
        sku: 7,
        item: "Peach",
        image: "https://infinityknow.com/241793/peach.jpg",
        itemdesc: "This is a peach",
        details: "This is where some detailes on peaches would go. Shout out peaches for being delicious.",
        productprice: 1.5
      },

      {
        sku: 8,
        item: "Mango",
        image: "https://infinityknow.com/241793/mango.png",
        itemdesc: "This is a mango",
        details: "This is where some detailes on mangos would go. Shout out mangos for being delicious.",
        productprice: 2
      },

      {
        sku: 9,
        item: "Cognac",
        image: "https://infinityknow.com/241793/cognac.jpg",
        itemdesc: "This is a glass of cognac",
        details: "This is where some detailes on cognac would go. I'm like hey whats up, hello.",
        productprice: 17.38
      },

      {
        sku: 10,
        item: "Chain",
        image: "https://infinityknow.com/241793/chain.jpg",
        itemdesc: "This is a chain",
        details: "This is where some details on chains would go. 2Chainz but I got me a few on.",
        productprice: 17.38
      }
    ],
    checkCartData: false,
    shopCrat: [],
    shopcartSubtotal: 0,
    billtax: 0.065,
    shptotal: 0
  }
  events: {
    "checkoutRequest": function() {
      vue.$broadcast("checkoutRequest");
    }
  }
});

Example

READ :  Angular 6 Interview Questions and Answers

I hope you have Got Shopping Cart Application using Vuejs And how it works.I would Like to have FeadBack From My Blog(infinityknow.com) readers.Your Valuable FeadBack,Any Question,or any Comments abaout This Article(infinityknow.com) Are Most Always Welcome.

Add a Comment

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