我想知道如何计算 vue.js 列表的总数。 我的情况有点复杂,所以请允许我举个例子。 假设我正在渲染一张发票项目表。这是我的代码:
<table>
<template v-for="(invoice_item, index) in invoice_items" v-if="invoice_item.category === 'widgets'">
<tr>
<td>@{{ invoice_item.name }}</td>
<td><input type="number" class="inline-edit" v-model="invoice_item.rate"></td>
<td><input type="number" class="inline-edit" v-model="invoice_item.quantity"></td>
<td><input type="number" class="inline-edit" v-model="invoice_item.activation_fee"></td>
<td class="subtotal">@{{ computeSubTotal(invoice_item) }}</td>
</tr>
</template>
</table>
对于每一行,我都计算了一个小计并将其显示在最后一列中。这是我的 vue.js javascript 中的代码:
computeSubTotal: function(invoice_item) {
return(this.formatPrice((parseFloat(invoice_item.rate) * parseFloat(invoice_item.quantity) + parseFloat(invoice_item.activation_fee))));
},
这很好用。但是,现在我想显示所有小计的总和。换句话说:
我该如何实现?
谢谢!
最佳答案
使用计算属性进行计算。
console.clear()
new Vue({
el: "#app",
data: {
invoice_items: [
{
name: "Community / Support",
rate: 5.20,
quantity: 1,
activation_fee: 3.00,
category: "widgets"
},
{
name: "Infrastructure",
rate: 269.00,
quantity: 3,
activation_fee: 1.00,
category: "widgets"
},
{
name: "Infrastructure",
rate: 269.00,
quantity: 3,
activation_fee: 1.00,
category: "stuff"
},
]
},
computed: {
// probably need a better name for this, but its just an example
itemsWithSubTotal() {
return this.invoice_items.map(item => ({
item,
subtotal: this.computeSubTotal(item)
}))
},
// calculate the total of all the subtotalItems grouped by category
totalByCategory() {
// group the items by category
let grouped = this.itemsWithSubTotal
.reduce((acc, val) => {
// This line does everything the lines below do, but in a very
// terse, possibly confusing way.
//(acc[val.item.category] = acc[val.item.category] || []).push(val)
//if there is not already an array set up for the current
//category, add one
if (!acc[val.item.category])
acc[val.item.category] = []
// push the current value into the collection of values
// for this category
acc[val.item.category].push(val)
// return the accumulator (object)
return acc
}, {})
// create an object that has the total for each category
return Object.keys(grouped).reduce((acc, val) => {
acc[val] = grouped[val].reduce((total, item) => total += item.subtotal, 0)
return acc
}, {})
}
},
methods: {
computeSubTotal: function(invoice_item) {
//formatPrice is removed here because its not defined in the question
return ((parseFloat(invoice_item.rate) * parseFloat(invoice_item.quantity) + parseFloat(invoice_item.activation_fee)));
},
}
})
input {
width: 5em
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<table>
<template v-for="(invoice_item, index) in itemsWithSubTotal" v-if="invoice_item.item.category === 'widgets'">
<tr>
<td>{{ invoice_item.name }}</td>
<td><input type="number" class="inline-edit" v-model="invoice_item.item.rate"></td>
<td><input type="number" class="inline-edit" v-model="invoice_item.item.quantity"></td>
<td><input type="number" class="inline-edit" v-model="invoice_item.item.activation_fee"></td>
<td class="subtotal">{{ invoice_item.subtotal }}</td>
</tr>
</template>
</table>
Total: {{totalByCategory["widgets"]}}
</div>
itemsWithSubTotal
可能看起来有点奇怪。
itemsWithSubTotal() {
return this.invoice_items.map(item => ({
item,
subtotal: this.computeSubTotal(item)
}))
},
基本上这会返回一个具有一个属性的新对象,item
指向原始项目和一个小计属性。我这样做是为了让 v-model
可以在模板中工作并自动更新计算属性。
关于javascript - Vue.js 使用 v-if 语句对列表进行小计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48433537/