Vue组件小计的总和

时间:2019-01-26 14:24:46

标签: javascript vue.js

我需要在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>

1 个答案:

答案 0 :(得分:1)

下面是修改后的代码,该代码将表单支出显示为您在每个预算部分下添加的多行支出总额:

添加了手表和计算的组合以实现此目的。以下是所做更改的高级摘要:

  • 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>