On gists
V-model in loops and computed
Vue.js
App.vue
Raw
#
/*
https://stackblitz.com/edit/superlasice-efzixd?file=src%2FApp.vue
*/
<template>
<div id="app">
<button v-on:click="add">add new row</button>
<p>Total price {{ total }} | {{ total2 }}</p>
<ul>
<li v-for="(item, index) in items">
Name<br />
<input type="text" v-model="item.name" />
<br />
Quantity<br />
<input type="number" v-model.number="item.quantity" min="1" />
<br />
Price<br />
<input
type="number"
v-model.number="item.price"
min="0.00"
max="10000"
step="1"
/>
<br />
Total (readonly) <br />
<input v-model="totalItems[index]" readonly /> <br />
total in row:
{{ totalItem(item) }}
<br />
<br />
<button v-on:click="remove(index)">Delete row</button>
<hr />
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
items: [
{ name: 'A', quantity: 1, price: 20 },
{ name: 'B', quantity: 2, price: 30 },
],
};
},
methods: {
add() {
this.items.push({
name: 'New product',
quantity: 0,
price: 0,
});
},
remove(index) {
this.items.splice(index, 1);
},
totalItem(item) {
return item.price * item.quantity;
},
},
computed: {
totalItems() {
let arr = [];
this.items.forEach((item) => {
arr.push(parseFloat(item.price) * parseFloat(item.quantity));
});
return arr;
},
total() {
let sum = 0;
this.items.forEach((item) => {
sum += parseFloat(item.price) * parseFloat(item.quantity);
});
return sum;
},
// another approach how to sum
total2() {
return this.items.reduce((prev, item) => {
return prev + item.price * item.quantity;
}, 0);
},
},
};
</script>
App2.vue
Raw
#
/* https://stackblitz.com/edit/vmodel-loop-v2?file=src%2Fcomponents%2FFormRow.vue */
<template>
<div id="app">
Celková cena je: {{ totalPrice }}
<br />
<button @click="addNewRow">add new row</button>
<FormRow
v-for="(item, index) in items"
:key="item.name"
v-model="items[index]"
/>
</div>
</template>
<script>
import FormRow from './components/FormRow';
export default {
name: 'App',
components: {
FormRow,
},
data() {
return {
items: [
{
name: 'A',
quantity: 1,
price: 10,
},
{
name: 'B',
quantity: 2,
price: 20,
},
],
};
},
computed: {
totalPrice() {
let total = 0;
this.items.forEach((item) => {
total += item.price * item.quantity;
});
return total;
},
},
methods: {
addNewRow() {
this.items.push({
name: null,
quantity: 0,
price: 0,
});
},
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin-top: 60px;
}
</style>
FormRow.vue
Raw
#
<template>
<div>
<input v-model="modelValue.name" />
<input type="number" v-model="modelValue.quantity" />
<input type="number" v-model="modelValue.price" />
<input v-model="sum" disabled />
<hr />
</div>
</template>
<script>
export default {
name: 'FormRow',
props: ['modelValue'],
computed: {
sum() {
return this.modelValue.quantity * this.modelValue.price;
},
},
};
</script>
<style>
input {
width: 100px;
margin: 5px;
}
</style>