Vue.js实现动态添加行的数值求和问题
Hey there! Let's work through your two key challenges: simplifying how you access the service price and adding a total sum calculation for all rows.
1. Clean Up Service Price Access (No More String Splitting!)
Instead of concatenating item.id+'|'+item.price into the select's value and parsing it later, you can directly bind the entire service object to your select. This lets you access the price directly without messy filters or string manipulation.
Here's how to adjust your code:
- Add a
selectedServiceproperty to each row object to hold the chosen service. - Bind the select's
v-modeltorow.selectedServiceinstead of a concatenated string. - When a service is selected, reference
row.selectedService.pricedirectly for calculations.
Example snippet:
<tr v-for="(row, index) in rows" :key="index"> <td> <select v-model="row.selectedService"> <option v-for="service in services" :value="service"> {{ service.name }} </option> </select> </td> <td> <input type="number" v-model.number="row.quantity" min="1" /> </td> <td> {{ calculateRowTotal(row) }} </td> </tr>
Add a method to compute the row total with the 10% discount:
methods: { calculateRowTotal(row) { if (!row.selectedService || !row.quantity) return 0; const discountedPrice = row.selectedService.price * 0.9; // Apply 10% discount return discountedPrice * row.quantity; } }
2. Calculate Total Sum of All Rows
To get the grand total across all rows, create a computed property that iterates through your rows array, sums up each row's calculated total.
Add this to your Vue component:
computed: { totalSum() { return this.rows.reduce((total, row) => { return total + this.calculateRowTotal(row); }, 0); } }
Then display the total in your template:
<div class="total-container"> <strong>Grand Total: {{ totalSum }}</strong> </div>
Bonus: Polish the "Add New Row" Logic
Make sure your trigger for adding rows (selecting "Service" in the last row) works smoothly. You can use a watcher to detect changes in the last row's selection:
watch: { 'rows[-1].selectedService'(newService) { if (newService && newService.name === 'Service') { this.rows.push({ selectedService: null, quantity: 1 }); } } }
This will automatically add a new empty row every time you select "Service" in the final row.
内容的提问来源于stack exchange,提问作者Space Peasant

