javascript - Vue 组件小计之和
问题描述
我需要在我的 Vue 应用程序中添加小计。
每个组件都有基于用户输入的自己的小计。然后需要将这些添加到组件之外的另一个输入中。
我一直被困在如何最好地引用组件之外的组件小计。这最好通过向#app 添加计算属性来完成吗?
<div id="app">
<h1 style="padding: 2em 0 1em">Vue.JS Loop 2</h1>
<div class="total">
<input :value="form.income" @change="updateIncome" type="number" class="form-control" name="income" id="income" placeholder="Income">
<!--Add all subtotals here-->
<input :value="form.expenses" @change="updateExpenses" type="number" step="any" class="form-control" name="expenses" id="expenses" placeholder="Expenses">
<hr/>
<input v-model="form.dispIncome" type="number" step="any" class="form-control" name="dispIncome" id="dispIncome" placeholder="Disposable Income">
</div>
<div class="budget-container">
<div class="budget" v-for="budget in budgets">
{{budget}} Expenses
<budget-line></budget-line>
</div>
</div>
</div>
<script>
var budgetLine = Vue.extend({
template: `
<div>
<p id="result"><strong>Total:</strong> $ {{ totalQty }} </p>
<div class="row" v-for="item in items">
<input type="text" placeholder="Item"></input>
<input type="text" placeholder="How much?" v-model="item.qty"></input>
<button @click="addItem">+</button>
<button @click="removeItem">-</button>
</div>
</div>
`,
data: function() {
return { items: [] };
},
computed: {
totalQty() {
return this.items.reduce((total, item) => {
return total + Number(item.qty);
}, 0);
},
},
methods: {
addItem() {
this.items.push({
qty: 0
});
},
removeItem(item) {
this.items.pop(item);
}
},
mounted() {
this.addItem()
}
});
var budgetApp = new Vue({
el: '#app',
data: {
budgets: ['One', 'Two', 'Three'],
form: {
income: 0,
expenses: 0,
dispIncome: 0
}
},
components: {
'budget-line': budgetLine
},
methods: {
updateIncome(event) {
this.form.income = event.target.value
this.form.dispIncome = this.form.income - this.form.expenses
},
updateExpenses(event) {
this.form.expenses = event.target.value
this.form.dispIncome = this.form.income - this.form.expenses
}
}
});
</script>
解决方案
下面是修改后的代码,它将表单费用显示为您在每个预算部分下添加的多行费用总额:
添加了 watch 和 computed 的组合来实现这一点。以下是所做更改的高级摘要:
- 在
budgetLine
组件中添加了一个观察者来发出更改totalQty
- 在
budgetApp
组件中将预算数据修改为对象,将计算添加budgetKeys
到渲染部分名称,添加calculateExpense
将在从budgetLine 发出时调用的方法以更新预算和预算的观察者以更新form.expenses
var budgetLine = Vue.extend({
template: `
<div>
<p id="result"><strong>Total:</strong> $ {{ totalQty }} </p>
<div class="row" v-for="item in items">
<input type="text" placeholder="Item"></input>
<input type="text" placeholder="How much?" v-model="item.qty"></input>
<button @click="addItem">+</button>
<button @click="removeItem">-</button>
</div>
</div>
`,
data: function() {
return {
items: []
};
},
watch: {
totalQty(value) {
this.$emit('update-expense', value)
}
},
computed: {
totalQty() {
return this.items.reduce((total, item) => {
return total + Number(item.qty);
}, 0);
},
},
methods: {
addItem() {
this.items.push({
qty: 0
});
},
removeItem(item) {
this.items.pop(item);
}
},
mounted() {
this.addItem()
}
});
var budgetApp = new Vue({
el: '#app',
data: {
budgets: {
'One': 0,
'Two': 0,
'Three': 0
},
form: {
income: 0,
expenses: 0,
dispIncome: 0
}
},
components: {
'budget-line': budgetLine
},
watch: {
budgets: {
deep: true,
handler() {
this.form.expenses = this.budgetKeys.reduce((accum, key) => accum + this.budgets[key], 0)
}
}
},
computed: {
budgetKeys() {
return Object.keys(this.budgets)
},
},
methods: {
updateIncome(event) {
this.form.income = event.target.value
this.form.dispIncome = this.form.income - this.form.expenses
},
updateExpenses(event) {
this.form.expenses = event.target.value
this.form.dispIncome = this.form.income - this.form.expenses
},
calculateExpense(amount, budget) {
this.budgets[budget] = amount;
console.log(this.budgets)
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1 style="padding: 2em 0 1em">Vue.JS Loop 2</h1>
<div class="total">
<input :value="form.income" @change="updateIncome" type="number" class="form-control" name="income" id="income" placeholder="Income">
<!--Add all subtotals here-->
<input :value="form.expenses" @change="updateExpenses" type="number" step="any" class="form-control" name="expenses" id="expenses" placeholder="Expenses">
<hr/>
<input v-model="form.dispIncome" type="number" step="any" class="form-control" name="dispIncome" id="dispIncome" placeholder="Disposable Income">
</div>
<div class="budget-container">
<div class="budget" v-for="budget in budgetKeys">
{{budget}} Expenses
<budget-line v-on:update-expense="calculateExpense($event, budget)"></budget-line>
</div>
</div>
</div>
推荐阅读
- php - 电报机器人 api-php 中 sendMessage 方法中的 parse_mode
- inno-setup - 在 Inno Setup 安装向导结束时有条件地跳到自定义页面而不安装?
- mysql - 添加带有 3 个表的 COUNT(*)
- python - pandas DataFrame.to_sql 是否适用于 ipynb 文件?
- rust - 由于实验性功能,未安装 Rustlings
- html - 带环绕的内在中心对齐 div
- search - 使用 solr 进行离线聚类?
- python - 为什么当零除错误在 else 子句中但不在下面注释掉的行中时异常处理程序起作用
- c++ - 除了向后兼容性之外,还有什么理由 C++20 仍然包含 goto 作为语句?
- android-studio - 如何修复颤振 lib/main.dart 错误