Home > Enterprise >  Vue: How to update value onchange inside loop template?
Vue: How to update value onchange inside loop template?

Time:08-31

I have items array and taxes array for an invoice. And I have been trying to update the total sum value when the tax select field is changed but can't think of an exact solution as I can't pass the value to a total value ref or a watcher. Here is my code.

<template>
<div >
  <ul >
    <li v-for="item in items" :key="item.id">
      <h2 >{{ item.details }}</h2>

      <input type="number" v-model="item.qty"/>

      <select v-model="item.tax_id">
        <option v-for="tax in taxes" :key="tax.id" :value="tax.id">
          {{ tax.name }}
        </option>
      </select>

      <input type="number" v-model="item.rate" />

      <div >
        Total:
        <span v-if="item?.tax">
          {{
            itemWithTax(item.rate, item.qty, item.tax.rate)
          }}
        </span>
      </div>
    </li>
  </ul>
</div>
</template>
<script setup>
import { ref } from "vue";

const itemWithTax = (rate, qty, tax_rate) => {
    let total = rate * qty;
    let percent = tax_rate / 100;
    percent = total * percent;
    return total   percent;
};

const items = ref([
    {
        id: 1,
        tax_id: 1,
        details: "Neque offi",
        qty: 3,
        rate: 100,
        tax: {
            id: 1,
            name: "Service Tax",
            rate: 10,
        },
    },
    {
        id: 6,
        tax_id: 1,
        details: "Neque officiis molestiae.",
        qty: 5,
        rate: 310,
        tax: {
            id: 1,
            name: "Service Tax",
            rate: 10,
        },
    },
    {
        id: 7,
        tax_id: 2,
        details: "Totam ab cum.",
        qty: 4,
        rate: 820,
        tax: {
            id: 2,
            name: "GST",
            rate: 17,
        },
    },
    {
        id: 8,
        tax_id: 2,
        details: "Et aut aut.",
        qty: 3,
        rate: 140,
        tax: {
            id: 2,
            name: "GST",
            rate: 17,
        },
    },
]);

const taxes = [
    {
        id: 1,
        name: "Service Tax (10%)",
        rate: 10,
    },
    {
        id: 2,
        name: "GST (17%)",
        rate: 17,
    },
];
</script>

Here is the working Codesandbox. https://codesandbox.io/s/exciting-mountain-0fqkyf?file=/src/App.vue

Any help would be really appreciate.

Thanks.

CodePudding user response:

The simplest fix is to change the itemWithTax function like so

const itemWithTax = (rate, qty, tax_id) => {
  const tax_rate = taxes.value.find(({id}) => id === tax_id)?.rate
  let total = rate * qty;
  let percent = tax_rate / 100;
  percent = total * percent;
  return total   percent;
};

and call it like

itemWithTax(item.rate, item.qty, item.tax_id)

CodePudding user response:

You would need a computed Property to be able to perform the calculations when the reactive data changes and replace total with the computed property you've created. You can read up more on computed here https://vuejs.org/guide/essentials/computed.html

  • Related