[Vuejs]-How can I push input value from a custom input component into an array in the parent component?

1๐Ÿ‘

โœ…

So in the parent you can do like so:

<template>
  <div class="container">
    <h1>Budget Form</h1>

    <div class="form">
      <form action>
        <div class="topForm">
          <label for="monthlypay">Monthly pay</label>
          <input type="number" name="monthlypay" id="monthlypay" v-model="earnings">
        </div>
      </form>

      <h2>Expenses</h2>
      <form-input
        v-for="(n,idx) in count"
        :key="n"
        :id="idx"
        :e-key="expensesKey"
        @eKey="setExpenseKey"
        @input="getExpenseValue"
      ></form-input>

      <button @click="addInputs">Add Expense</button>
      <button @click="deleteInputs">Delete</button>
      <button type="button" @click="submitBudget">Submt</button>

      <p>Total Monthly Income: {{ earnings }}</p>
      <p>Total Expense: {{ totalExpense }}</p>
      <p>Money left: {{ getDifference }}</p>
    </div>
  </div>
</template>

<script>
import axios from "axios";
import formInput from "./components/Input.vue";

export default {
  components: {
    "form-input": formInput
  },
  name: "form",
  data() {
    return {
      count: 0,
      earnings: "",
      expensesValue: [],
      expensesKey: [],
      totalExpense: ""
    };
  },
  methods: {
    addInputs: function() {
      this.count++;
      this.expensesValue[this.count - 1] = 0;
      this.expensesKey[this.count - 1] = "default";
    },
    deleteInputs: function() {
      if (this.count < 1) {
        return;
      }

      this.count--;
      this.expensesValue.pop();
      this.expensesKey.pop();

      this.setTotalExpense();
    },
    getExpenseValue(data) {
      this.expensesValue[data.id] = parseInt(data.value, 10) || 0;
      this.setTotalExpense();
    },
    setExpenseKey(data) {
      this.expensesKey[data.id] = data.value || "default";
    },
    setTotalExpense() {
      console.log(this.expensesValue);

      this.totalExpense = this.expensesValue.reduce((sum, val) => {
        return sum + val;
      }, 0);
    },
    mergeKeyAndValue() {
      return this.expensesKey.reduce((acc, key, index) => {
        return [...acc, { [key]: this.expensesValue[index] }];
      }, []);
    },
    submitBudget() {
      const expenses = this.mergeKeyAndValue();

      axios
        .post("http://localhost:3000/budget", {
          earning: this.earnings,
          expenses
        })
        .then(response => {
          console.log(response.data);
        })
        .catch(e => {
          console.error(e);
        });
    }
  },
  computed: {
    getDifference() {
      return this.earnings - this.totalExpense;
    }
  }
};
</script>

And in the child, you can do like this:

<template>
  <div class="input">
    <input
      type="text"
      placeholder="Expense"
      @input="$emit('eKey', {
        value: $event.target.value,
        id
      })"
    >
    <input
      type="number"
      placeholder="Amount"
      @input="$emit('input', { 
        value: $event.target.value,
        id
      })"
    >
  </div>
</template>

<script>
export default {
  name: "formInput",
  props: {
    id: Number,
    eKey: Array
  }
};
</script>

Note, I also added a function that will pair the key and values together before posting the data. (I also added some other minor improvements).

You may want to adjust some things to suit your needs.

Let me know if you have any questions.

๐Ÿ‘คT. Short

Leave a comment