7even
7even

Reputation: 21

How to do summation in Vue

I'm quite new to coding (less than 3months old) and I'm currently trying to learn vue. I'm trying out this simple exercise of doing a basic shopping cart and I want to get the total of all the product amounts. Here is my code:

HTML

<template>
<div class="product" @click="isMilkshown = true">{{ productList[0].name }}&nbsp;&nbsp;&nbsp;$ {{ productList[0].amount }}</div>
<div class="product" @click="isFishshown = true">{{ productList[1].name }}&nbsp;&nbsp;&nbsp;$ {{ productList[1].amount }}</div>
<div class="product" @click="isLettuceshown = true">{{ productList[2].name }}&nbsp;&nbsp;&nbsp;$ {{ productList[2].amount }}</div>
<div class="product" @click="isRiceshown = true">{{ productList[3].name }}&nbsp;&nbsp;&nbsp;$ {{ productList[3].amount }}</div>

<!-- Cart -->
<div class="main-cart">
 <div>Cart</div>
 <div class="main-cart-list" v-for="product in productList" :key="product">
  <div v-if="showProduct(product.name)">{{ product.name }}&nbsp;&nbsp;&nbsp;$ {{ product.amount }}</div>
 </div>
 <div>Total: 0</div>
</div>
</template>

JS

export default {
data() {
 return {
  productList: [
    { name: "Milk", amount: 10 },
    { name: "Fish", amount: 20 },
    { name: "Lettuce", amount: 5 },
    { name: "Rice", amount: 2.5 }
  ],

  isMilkshown: false,
  isFishshown: false,
  isLettuceshown: false,
  isRiceshown: false
}
},

methods: {
  showProduct(name) {
    if (name === "Milk" && this.isMilkshown === false) {
    return false
   } else if (name === "Fish" && this.isFishshown === false) {
    return false
   } else if (name === "Lettuce" && this.isLettuceshown === false) {
    return false
   } else if (name === "Rice" && this.isRiceshown === false) {
    return false
   } else {
    return true
   }
  }
 }
}

I want to replace the "zero" in Total with the sum of all the product amounts when a product is clicked. Hope someone can help me, thanks!

Upvotes: 2

Views: 76

Answers (1)

Jordan
Jordan

Reputation: 2381

You would use a computed function.

https://v2.vuejs.org/v2/guide/computed.html

In Vue, computed functions watch all the reactive variables referenced within them and re-run to update the returned value when any of those variables change.

Simply create a computed function that loops over each productList item and sums up the amount then returns it.

You can reference this answer to learn how to sum using reduce or for a standard example with a loop Better way to sum a property value in an array

Also, you can use a v-for loop on your

<div class="product" @click="isMilkshown = true">{{ productList[0].name }}&nbsp;&nbsp;&nbsp;$ {{ productList[0].amount }}</div>

component so that you don't have duplicated code:

<div v-for="item in productList" key="item.name" class="product">{{ item.name }}&nbsp;&nbsp;&nbsp;$ {{ item.amount }}</div>

This would create one of each of those elements for each item in your productList variable.

You would then need to re-write the click handler to be dynamic too.

Lastly, you can also convert your big if/else-if chained method into a computed function too so that you watch for changes in that.

To do that, you'd make the computed return an object like this:

{
    Milk: true,
    Fish: false
    ...
}

You can put the key as the name so that in your loop you can reference the computed property like this enabledItems[item.name] to get the true/false.

Upvotes: 1

Related Questions